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

iOS C++/OC 混編

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