美文网首页iOSiOS学习游戏开发
oc与c++混编,抛弃.mm文件

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

作者: owlwisp | 来源:发表于2016-06-12 15:18 被阅读993次

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

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

    "COCFile.h"

    <pre> #import <Foundation/Foundation.h>
    @interface COCFile : NSObject{

    NSString * name_;
    NSNumber * count_;

    }

    @property (nonatomic, readwrite,copy) NSString * name_;
    @property (nonatomic, readwrite,retain) NSNumber * count_;
    @end</pre>

    "COCFile.m"

    <pre> #import "COCFile.h"
    @implementation COCFile
    @synthesize name_;
    @synthesize count_;

    -(id) init{
    if(self = [super init]) {
    name_ = @"text";
    count_ = [NSNumber numberWithInt:3];
    }
    return self;
    }
    @end</pre>

    编译,测试没问题,我们进入下一步

    state_1: 头文件内不包含oc 语言的混编

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

    "COCFile_State_1.h"

    <pre> #include <iostream>
    #include "CSingleton.h"
    class CState_1 : public Singleton
    {
    public:
    const char * getName();
    int getCount();
    const char * getMode();
    };</pre>

    "COCFile_State_1.mm"

    <pre> #include "COCFile_State_1.h"
    #import "COCFile.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];
      }</pre>
    
    1. 这样就可以在"HelloWorldScene"中调用这2个方法来获取原来在oc中的数据了.代码如下:
      <pre> 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</pre>

    备注:这里举的例子可能不够恰当(主要是跟state2做对比),因为这种混编的情况比较实用于oc是单例类的情况。例如系统设备的 "UIDevice" 等比较合适.

    state_2:头文件也需要被包含的情况,其实这就是一个转化,只需要在多包含一层就可以了,然后转化成state_1 来解决

    1.我们建立一个 "COCFileState_2_Mid.mm" 的中间类,用来封装oc的代码, 代码很简单如下:

    "COCFileState_2_Mid.h"

    <pre> #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();
    };</pre>

    "COCFileState_2_Mid.mm"

    <pre> 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;
    }</pre>

    2.下面的方法估计你看了会感觉很熟悉,是的 下面就是重复state_1那就直接上代码嘛

    "CState_2.h"

    <pre> #include < iostream >

    include "CSingleton.h"

    class CState_2:public Singleton{

    public:
    const char * getName();
    int getCount();
    };</pre>

    "CState_2.mm"

    <pre> #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];
    }</pre>

    3.这样就可以在HelloWorldScene中调用这2个方法来获取原来在oc中的数据了。代码如下:
    <pre> 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转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文件

      本文链接:https://www.haomeiwen.com/subject/djiedttx.html