1. 程式人生 > >OC 和C++ 混編

OC 和C++ 混編

先說題外話,文章標題其實起的不好,在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》