cocos2dxにC++とObjective-Cの共存

ChainZ(クリエイター)
いろいろやってます。

cocos2dxで作成したゲームにソーシャル機能を入れたい時に、プラットフォームによって実装方法が変わります。もちろん、ゼロから自分でC++でライブラリを書くのもありですが、できれば各プラットフォーム自体を提供したAPIを使ったほうが無難です。

しかし、iOSはobjective-C、AndroidはJavaを使用しています。直接そのAPIは利用できません。C++でそのAPIにアクセスする方法を考えなくてはいけません。

C++とObjective-Cの共存

Objective-CはCをベースにした言語です。Cと共存できるC++は、Objective-Cとも共存できます。実xcodeではC++をObjective-Cと共存させるのが非常に簡単です。ソースの拡張子をmmにすればいいのです

こうすればいい

例えば新規したcocos2dxのプロジェクトにHelloWorldScene.cppというファイルがあります。それをHelloWorldScene.mmにリネームすれば、中にObjective-Cを書いてxcodeはちゃんとコンパイルしてくれます。

cocos2dxでObjective-Cを使ってHello,World!

準備

振起したcocos2dxプロジェクトにあるHelloWorldScene.cppの拡張子をmmにします。これからObjective-Cを書くわけですが、cocos2dxはプラットフォーム別けにマクロを用意しました。

#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    // ここにiOSプラットフォーム用コードを書く
#endif

早速使ってみよう、#include "HelloWorldScene.h"の直後に下記のコード追加

#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    #import <Foundation/Foundation.h>
#endif

Objective-Cでは#includeではなく、#importを使っています。そして<Foundation/Foundation.h>ですが、これはiOSアプリ開発用言語cocoaの基盤ライブラリです。これをimportすることで、NSString,NSArrayなどcocoaのオブジェクトが使えるようになります。

ネームスペース衝突

<Foundation/Foundation.h>importすると、このようなエラーが出てくるはずです。

エラー

これは,Objective-CにもSizeという構造体があるからです、解決方法は簡単です。ネームスペースをつけてあげれば良い。

cocos2d::Size visibleSize = Director::getInstance()->getVisibleSize();

NSStringを作成

NSStringはObjective-Cの文字列オブジェクトです。下記ように作成できます。

NSString* helloWorldAsString = @"Hello World";

Objective-Cの文字列前に@をつけるのが一般的です。さて、それをC++のcocos2dxで表示させよう。普通にC++書けば良いです。

// Objective-Cです
NSString *helloWorldAsString = @"Hello World";

// C++です
auto label = cocos2d::Label::createWithSystemFont([helloWorldAsString UTF8String], "HiraKaku-W6", 36);
// ラベル作成

label->setPosition(visibleSize/2);
// ポジションをセット

this->addChild(label);
// レンダリング

cocos2d::Label::createWithSystemFontの一番目のパラメターに[helloWorldAsString UTF8String]をパスしました。[helloWorldAsString UTF8String]はObjective-Cの文法で、C++で解釈するとhelloWorldAsString->UTF8String()という感じです。UTF8Stringメソードを利用して、NSStringの文字列をCのchar*型に変換できます。コンパイルしてみると:

結果

成功しました!

感想

xcodeのおかげで、C++とObjective-Cとの共存は簡単にできちゃいます。今度はJavaとの連携を書いてみます。でもC++とJavaとの連携は意外と面倒くさいので、時間がかかるかもしれません。。