寫這片文章的起因是箫锤,有些朋友不想使用oc++的全部.mm文件的寫法贬蛙,固才有這種混編的轉(zhuǎn)化的方法前期準備:
- 首先建立一個新工程,編譯,運行谚攒,ok 沒問題阳准,進入第2步
- 我建立了一個 "COCFile.m" 的文件,用來儲存oc語言的代碼,代碼如下:
"COCFile.h"
#import <Foundation/Foundation.h>
@interface COCFile : NSObject{
NSString * name_;
NSNumber * count_;
}
@property (nonatomic, readwrite,copy) NSString * name_;
@property (nonatomic, readwrite,retain) NSNumber * count_;
@end
"COCFile.m"
#import "COCFile.h"
@implementation COCFile
@synthesize name_;
@synthesize count_;
-(id) init{
if(self = [super init]) {
name_ = @"text";
count_ = [NSNumber numberWithInt:3];
}
return self;
}
@end
編譯馏臭,測試沒問題野蝇,我們進入下一步
state_1: 頭文件內(nèi)不包含oc 語言的混編
- 我們建立一個 "COCFile_State_1.cpp" 的中轉(zhuǎn)類,將尾綴修改為".mm ".并將頭文件放到 "HelloWorldScene.m"中,編譯測試括儒。沒問題绕沈,下一步。
- 在 "COCFile_State_1”創(chuàng)建一個c++的類帮寻,你可以選擇用普通或者是單例都沒問題.那么我們需要在這個類中調(diào)用 "COCFile" 的oc的代碼乍狐,代碼如下
"COCFile_State_1.h"
#include <iostream>
#include "CSingleton.h"
class CState_1 : public Singleton
{
public:
const char * getName();
int getCount();
const char * getMode();
};
"COCFile_State_1.mm"
#import "COCFile.h"
#include "COCFile_State_1.h"
const char * CState_1::getName(){
COCFile * file = [[[COCFile alloc]init]autorelease];
return [file.name_ UTF8String];
}
int CState_1::getCount(){
COCFile * file = [[[COCFile alloc]init]autorelease];
return [file.count_ intValue];
}
const char * CState_1::getMode(){
return [[UIDevice currentDevice].model UTF8String];
}
- 這樣就可以在"HelloWorldScene"中調(diào)用這2個方法來獲取原來在oc中的數(shù)據(jù)了.代碼如下:
const char * name = CState_1::getInstance()->getName();
int count = CState_1::getInstance()->getCount();
const char * mode = CState_1::getInstance()->getMode();
CCLOG("name = %s",name);
CCLOG("count = %d",count);
CCLOG("mode = %s",mode);
輸出如下:
Cocos2d: name = text
Cocos2d: count = 3
Cocos2d: mode = iPhone Simulator
備注:這里舉的例子可能不夠恰當(主要是跟state2做對比),因為這種混編的情況比較實用于oc是單例類的情況规婆。例如系統(tǒng)設備的 "UIDevice" 等比較合適.
state_2:頭文件也需要被包含的情況,其實這就是一個轉(zhuǎn)化澜躺,只需要在多包含一層就可以了,然后轉(zhuǎn)化成state_1 來解決
1.我們建立一個 "COCFileState_2_Mid.mm" 的中間類抒蚜,用來封裝oc的代碼掘鄙, 代碼很簡單如下:
"COCFileState_2_Mid.h"
#include "CSingleton.h"
#import "COCFile.h"
class CState_2_Mid :public Singleton{
private:
COCFile * m_ocFile;
~CState_2_Mid();
public:
CState_2_Mid();
COCFile getFile();
};
"COCFileState_2_Mid.mm"
CState_2_Mid::~CState_2_Mid(){
[m_ocFile release];
m_ocFile = NULL;
}
CState_2_Mid::CState_2_Mid(){
m_ocFile = [[COCFile alloc]init];
}
COCFile * CState_2_Mid::getFile(){
return m_ocFile;
}
2.下面的方法估計你看了會感覺很熟悉,是的 下面就是重復state_1那就直接上代碼嘛
"CState_2.h"
#include < iostream >
#include "CSingleton.h"
class CState_2:public Singleton{
public:
const char * getName();
int getCount();
};
"CState_2.mm"
#include "COCFileState_2.h"
#import "COCFileState_2_Mid.h"
const char * CState_2::getName(){
COCFile * file = CState_2_Mid::getInstance()->getFile();
return [file.name_ UTF8String];
}
int CState_2::getCount(){
COCFile * file = CState_2_Mid::getInstance()->getFile();
return [file.count_ intValue];
}
3.這樣就可以在HelloWorldScene中調(diào)用這2個方法來獲取原來在oc中的數(shù)據(jù)了嗡髓。代碼如下:
const char * name_1 = CState_2::getInstance()->getName();
int count_1 = CState_2::getInstance()->getCount();
CCLOG("name_1 = %s",name_1);
CCLOG("count_1 = %d",count_1);
輸出如下:
Cocos2d: name_1 = text
Cocos2d: count_1 = 3</pre>
OC轉(zhuǎn)c++就是這兩種情況操漠。C++轉(zhuǎn)oc也是類似的情況。
思考:
- 其實我們可以仔細看一眼state_2的步驟2,3和state_1的步驟2,3有什么區(qū)別?
- 有沒有發(fā)現(xiàn)其實拋去方法來看浊伙,他們都只是一個遵守一個規(guī)則的撞秋?
原則:c++寫在 .cpp中, oc 寫在.m 中嚣鄙,oc與c++混編那么就需要.mm吻贿。
那么我在c++中調(diào)用c++的代碼總沒問題把,這樣只需要.cpp就可以了. oc的同理
所以哑子,你只需要想盡一切辦法 將oc的方法 轉(zhuǎn)化成一個個c/c++接口來給c++調(diào)用就可以了舅列。
好吧就寫道這里了。估計現(xiàn)在你應該很清楚怎樣去混編c++與oc 了
另:可能上面步驟比較羅嗦卧蜓,但我還是比較喜歡這種小步進步帐要,步步為營的方式,這樣不會出現(xiàn)非常嚴重的問題弥奸,也不會突然束手無策榨惠。