[cocos2d-x / ios篇]教學3︰使用EasyNDK從Objective-C端呼叫回C++

文章撰寫日期︰2013/12/29 17:40
cocos2d-x使用版本︰2.1.4

一、前言

前一篇我們學會了使用EasyNDK從C++呼叫到Objective-C後,
現在再來學習怎麼從Objective-C呼叫回C++端。

這是一個很實用的例子,
我們可能會在Objective-C端寫一個檢查有無網路連線的功能,
然後從遊戲C++端發岀詢問。
等待Objective-C檢查到網路狀態後,
再回傳到遊戲C++裡通知遊戲主體

這篇的使用是繼前一篇攢寫的。
請確定已經明白之前的教學。

二、文章開始

實作C++端

修改剛才在HelloWorldScene.cpp裡按鈕觸發後的函式如下︰
void HelloWorld::menuCloseCallback(CCObject* pSender)
{
    CCLog(__FUNCTION__);
    // 在公域環境裡註冊一個selector
    // Objective-C端會以下列寫到的String來呼叫對應的函式
    // 註 : HelloWorldSelectors 為 Group name,
    // 這是 之後可以輕易讓我們從公域環境裡反註冊用的標籤。
    NDKHelper::AddSelector("HelloWorldSelectors",
                           "SampleSelectorInCPP",
                           callfuncND_selector(HelloWorld:: SampleSelectorInCPP),
                           this);
    
    // 傳送帶有 參數 的 message 給 Objective-C
    // 為了讓你明瞭,
    // 我們把等等會被Obj-C呼叫的C++函式名稱 SampleSelectorInCPP 傳岀去
    CCDictionary* prms = CCDictionary::create();
    prms->setObject(CCString::create("SampleSelectorInCPP"), "to_be_called");

    // 這是我們前一篇教的,要從C++呼叫Obj-C的 函式SampleSelector 的方式
    SendMessageWithParams(string("SampleSelector"), prms);
}

然後,我們替HelloWorldScene.h加入建構子與反建構子,
並且宣告函式SampleSelectorInCPP
#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__

#include "cocos2d.h"

class HelloWorld : public cocos2d::CCLayer
{
public:
    HelloWorld();//加上這個
    ~HelloWorld();//加上這個
    void SampleSelectorInCPP(CCNode *sender, void *data);//加上這個

    virtual bool init();  
    static cocos2d::CCScene* scene();
    void menuCloseCallback(CCObject* pSender);
    CREATE_FUNC(HelloWorld);
};

#endif // __HELLOWORLD_SCENE_H__

在HelloWorldScene.cpp的反建構子裡攢寫欲反註冊的Group name︰HelloWorldSelectors
HelloWorld::~HelloWorld(){
    // 由於我們即將銷毀HelloWorldScene這個實例instance,
    // 因此要從公域空間裡移除連結的Group︰HelloWorldSelectors
    NDKHelper::RemoveSelectorsInGroup("HelloWorldSelectors");
}

然後實作函式SampleSelectorInCPP
void HelloWorld:: SampleSelectorInCPP(CCNode *sender, void *data)
{
    CCLog("這裡是C++端,我們收到從Obj-C傳來的呼叫了");
}

實作Objective-C端

修改在前一篇裡我們用的函式SampleSelector︰
- (void) SampleSelector:(NSObject *)prms
{
    NSLog(@"Objective-C端的SampleSelector被呼叫了");
    
    // 抓取剛才從C++傳來會被呼叫的函式,
    // 由於剛才是用 參數 的方式傳來C++端的函式名稱
    // 因此我們要使用objectForKey的方式依 key值 取 value
    NSString* CPPFunctionToBeCalled = (NSString*)[parameters objectForKey:@"to_be_called"];
    
    // Show a bogus pop up here
    UIAlertView *message = [[UIAlertView alloc] initWithTitle:@"Hello World!"
                                                      message:@"This is a sample popup on iOS"
                                                     delegate:nil
                                            cancelButtonTitle:@"OK"
                                            otherButtonTitles:nil];
    [message show];
    
    // 倘若公域空間裡有 函式SampleSelectorInCPP
    // C++端 將會接收到從這裡傳岀的 message 和 其它字串
    [IOSNDKHelper SendMessage:CPPFunctionToBeCalled WithParameters:nil];
}

成功了!

除了跳岀UIAlertView以外,
從Xcode的console視窗我們還看到了從Obj-C呼叫觸發的C++端函式SampleSelectorInCPP

三、結論

前前篇前一篇和此篇,
已經完整的說明如何使用EasyNDK來方便完成

1. C++ → Objtive-C
2. Objtive-C → C++

的溝通。

感謝您的閱讀,
我也將這三篇使用的源碼放於此供大家下載
讓大家更明白。

專案在解壓後的proj.ios裡,
使用Xcode打開後,
記得將裡面cocos2d的專案路徑設到您的環境目錄裡方可執行。

相關文章

1. 在Android端使用EasyNDK

沒有留言 :

張貼留言