oc与c++混编,抛弃.mm文件

写这片文章的起因是,有些朋友不想使用oc++的全部.mm文件的写法,固才有这种混编的转化的方法前期准备:

  1. 首先建立一个新工程,编译,运行,ok 没问题,进入第2步
  2. 我建立了一个 "COCFile.m" 的文件,用来储存oc语言的代码,代码如下:

"COCFile.h"

#import  

@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: 头文件内不包含oc 语言的混编

  1. 我们建立一个 "COCFile_State_1.cpp" 的中转类,将尾缀修改为".mm ".并将头文件放到 "HelloWorldScene.m"中,编译测试。没问题,下一步。
  2. 在 "COCFile_State_1”创建一个c++的类,你可以选择用普通或者是单例都没问题.那么我们需要在这个类中调用 "COCFile" 的oc的代码,代码如下

"COCFile_State_1.h"

  #include 
  #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];
  }
  1. 这样就可以在"HelloWorldScene"中调用这2个方法来获取原来在oc中的数据了.代码如下:
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是单例类的情况。例如系统设备的 "UIDevice" 等比较合适.

state_2:头文件也需要被包含的情况,其实这就是一个转化,只需要在多包含一层就可以了,然后转化成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中调用这2个方法来获取原来在oc中的数据了。代码如下:

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

OC转c++就是这两种情况。C++转oc也是类似的情况。

思考:

  1. 其实我们可以仔细看一眼state_2的步骤2,3和state_1的步骤2,3有什么区别?
  2. 有没有发现其实抛去方法来看,他们都只是一个遵守一个规则的?

原则:c++写在 .cpp中, oc 写在.m 中,oc与c++混编那么就需要.mm。

那么我在c++中调用c++的代码总没问题把,这样只需要.cpp就可以了. oc的同理
所以,你只需要想尽一切办法 将oc的方法 转化成一个个c/c++接口来给c++调用就可以了。
好吧就写道这里了。估计现在你应该很清楚怎样去混编c++与oc 了

另:可能上面步骤比较罗嗦,但我还是比较喜欢这种小步进步,步步为营的方式,这样不会出现非常严重的问题,也不会突然束手无策。

你可能感兴趣的:(oc与c++混编,抛弃.mm文件)