zoukankan      html  css  js  c++  java
  • iPhone开发中,在XCode下混合编译C++/ObjectiveC

    先说题外话,文章标题其实起的不好,在iOS的开发中,Apple建立的库基本都是用Objective-C写的,所以在这里的C++指的其实是Objective-C++。

    首先,最最最要紧的事情,不是代码而是编译器选项,在做混合编译之前一定要把编译器的Compile Sources As选项改为Objective C++。

    默认的选项是According to file type,用这个的话,你后面每个不在交叉行列里的类都OK,一旦两种语言在一个文件中相互调用,就会报错,而且报的错怪的很,比如:找不到new,找不到delete,等等。

    既然是调用嘛,肯定要有来有往,先说说,在C++中如何调用Objective-C:(参考这个,我略做修改

    1. 封装Objective-C的对象函数变为C的函数接口

    2. 写一个对应的C++类调用

    说起来简单,看看例子就知道什么情况了。

    //MyObject-C-Interface.h

    #ifndef __MYOBJECT_C_INTERFACE_H__
    #define __MYOBJECT_C_INTERFACE_H__ 1

    int MyObjectDoSomethingWith (void *myObjectInstance, void *parameter);

    #endif

    //MyObject.h

    #import 
    "MyObject-C-Interface.h"

    @interface MyObject : NSObject
    {
        
    int someVar;
    }

    - (int) doSomethingWith:(void *) aParameter;
    @end

    //MyObject.m

    #import 
    "MyObject.h"

    int MyObjectDoSomethingWith (void *self, void *aParameter)
    {
        
    return [(id) self doSomethingWith:aParameter];
    }

    @implementation MyObject

    - (int) doSomethingWith:(void *) aParameter
    {
        
    // ... some code
        return 1;
    }

    @end

    //MyCPPClass.h
    #ifndef __MYCPPCLASS_H__
    #define __MYCPPCLASS_H__

    class MyCppClass
    {
    public:
         
    int MyCPPClass::someMethod (void *objectiveCObject, void *aParameter);
    }

    #endif

    //MyCPPClass.cpp

    #include 
    "MyCPPClass.h"
    #include 
    "MyObject-C-Interface.h"

    int MyCPPClass::someMethod (void *objectiveCObject, void *aParameter)
    {
        
    return MyObjectDoSomethingWith (objectiveCObject, aParameter);
    }

    如上面所示,先搞个弱类型的C函数接口,然后在Objective C的类中实现该接口。最后,在C++的类中调用弱类型,和弱接口。

    在工程主体框架是用Objective-C写成的前提下,上面的这种调用并不实用,完全是技术可能性的研究。说白了,就是骗骗编译器玩,同时也失去了C++优雅的强类型特性。

    下面这个才是真金白银有用的,在Objective-C代码下调用C++类代码:

    1. 建立一个C++类

    2. 写一个Adaptor的Objective-C类

    3. 在其他Objective-C的逻辑中调用Adaptor类。

    还是代码:)

    //
    //  CPlusPlusClass.h
    //  MixCompileTest
    //
    //  Created by biosli on 11-4-30.
    //  Copyright 2011 __MyCompanyName__. All rights reserved.
    //

    #ifndef __CPLUSPLUS_CLASS_H__
    #define __CPLUSPLUS_CLASS_H__

    class CPlusPlusClass {
    public:
        CPlusPlusClass();
        
    virtual ~CPlusPlusClass();
        
    void func();
        
    void setInt (int i) {
            m_i 
    = i;
        }
        
    private:
        
    int m_i;
    };


    #endif

    //
    //  CPlusPlusClass.mm
    //  MixCompileTest
    //
    //  Created by biosli on 11-4-30.
    //  Copyright 2011 __MyCompanyName__. All rights reserved.
    //

    #include 
    <stdio.h>
    #include 
    "CPlusPlusClass.h"

    CPlusPlusClass::CPlusPlusClass() : m_i(
    0
    {
        printf(
    "CPlusPlusClass::CPlusPlusClass()\n");
        func();
    }

    CPlusPlusClass::
    ~CPlusPlusClass() 
    {
        printf(
    "CPlusPlusClass::~CPlusPlusClass()\n");
    }

    void CPlusPlusClass::func() {
        printf(
    "CPlusPlusClass func print: %d\n", m_i);
    }

    //
    //  ObjectiveCAdaptor.h
    //  MixCompileTest
    //
    //  Created by biosli on 11-4-30.
    //  Copyright 2011 __MyCompanyName__. All rights reserved.
    //

    #import 
    <Foundation/Foundation.h>

    class CPlusPlusClass; //这个声明得小心,千万不要写成@class,兄弟我搞了半宿才找到这个错误。呵呵,见笑,见笑。

    @interface ObjectiveCAdaptor : NSObject {
    @private
        CPlusPlusClass 
    *testObj;
    }

    - (void) objectiveFunc;
    @end

    //
    //  ObjectiveCAdaptor.m
    //  MixCompileTest
    //
    //  Created by biosli on 11-4-30.
    //  Copyright 2011 __MyCompanyName__. All rights reserved.
    //

    #import 
    "ObjectiveCAdaptor.h"
    #include 
    "CPlusPlusClass.h"

    @implementation ObjectiveCAdaptor

    - (id) init {
        
    if (self = [super init]) {
            testObj 
    = new CPlusPlusClass();
        }
        
        
    return self;
    }

    - (void) dealloc {
        
    if (testObj != NULL) {
            delete testObj;
            testObj 
    = NULL;
        }
        [super dealloc];
    }

    - (void) objectiveFunc
    {
        testObj
    ->setInt(5);
        testObj
    ->func();

    @end

    //调用示例:
    - (void) callObjectiveCAdaptorMethod
    {
        ObjectiveCAdaptor 
    *testObjectiveCObj = [[ObjectiveCAdaptor alloc] init];
        [testObjectiveCObj objectiveFunc];
        [testObjectiveCObj release];
    }

     上面这个例子演示了创建C++类,创建Objective-C的Adaptor类,和最后调用的全过程。

    在编写混合编译代码时一定要记住一个原则,Objective-C++这个东东包含了Objective-C和C++的所有关键字和符号,所以在编写交叉编译代码时,千万不要用混本来就很像的关键字和符号。

    参考资料:

    具体的代码限制:请参考《Objective-C和C++混编的要点》

    混合编译好处多,这篇文章叙述的相当到位《Strategies for Using C++ in Objective-C Projects》

  • 相关阅读:
    【leetcode】下一个排列
    【leetcode】配对交换
    【leetcode】两个相同字符之间的最长子字符串
    052-126&127
    052-125
    052-124
    052-123
    052-122
    052-121
    052-120
  • 原文地址:https://www.cnblogs.com/biosli/p/Mixing_ObjectiveC_and_Cplusplus_in_iPhone_Development.html
Copyright © 2011-2022 走看看