Cocos2d-x項目移植到WP8系列之三:C++和C#的交互


 原文鏈接: http://www.cnblogs.com/zouzf/p/3971021.html

 

上一篇提到工程使用 XAML 和 Direct3D 項目模板 是因為要涉及到C++和C#的交互,微軟給我們提供了一個叫運行時組件的東西(也就是 windows phone 運行時組件 模板,一下簡稱winRT組件)來實現兩者的交互。winRT組件 工程里用的C++/CX語言(關於winRT自行谷歌),但完全兼容C++。在winRT組件 工程里,里面定義的類和方法只要符合一定的規范,就能被C#的工程直接訪問到,那C++如何訪問C#呢?畢竟,在Cocos2dx-wp8框架里,除了一開始啟動是從xaml-C# 端開始之外,后面的運行都是在C++工程里,只是在有必要的時候,C++才會訪問回C#,谷歌了一下,主流的解決方法是利用callback的思想實現,可以看看別人的實現: WP8:在WinRT組件(C++)中調用C#類庫的解決方案  Calling C# method from C++ code in WP8  。

 

上面兩篇文章基本上已經把C++和C#的交互這個問題比較清晰地解決掉了,但只是在winRT組件的C++和C#工程交互,而在我項目的具體實現里要求類似如下:C#工程依賴winRT工程,winRT工程依賴其他工程如Cocos2d工程(公司框架是直接在Cocos2d-x框架的源碼基礎上修改和增加,而不是使用Cocos2d-x項目生成的DLL)。如果Cocos2d工程有需要訪問C#的話,怎么辦?畢竟,Cocos2d工程才是作為主游戲邏輯的工程,而winRT工程更多是偏向於通道的作用,總不能把游戲邏輯的東西都挪到winRT工程里吧(雖然Cocos2d-x自帶的HelloCpp例子是這樣子做的~~)。

 

下面說一下個人的實現

前半段和上面那兩個鏈接一樣,實現winRT組件訪問C#,需要注意的是在定義ICallxxx 接口的那個h文件里,別include太多自己的頭文件,否則 被include的頭文件 以及 被include的頭文件里include的頭文件(遞歸)所在的路徑都要加到工程頭文件依賴里。

后半段,在主游戲邏輯所在的工程里(winRT組件工程依賴主游戲邏輯工程),實現一個單例類,主要就是定義一個函數指針 void (*FunCallCS_ImageCropper)();//, h文件如下:

 1 class  WZCallCS_And_BackToLua_Image
 2 {
 3 public:
 4 
 5     static WZCallCS_And_BackToLua_Image* Share_GetInstance();
 6         
 7     void (*FunCallCS_ImageCropper)();//在CX里被實現為調用CS的方法
 8 
 9 private:
10 
11     static WZCallCS_And_BackToLua_Image* m_pInstance;
12 
13     WZCallCS_And_BackToLua_Image();
14     ~WZCallCS_And_BackToLua_Image();
15 
16     //把復制構造函數和=操作符也設為私有,防止被復制,只聲明不實現,為什么?
17     WZCallCS_And_BackToLua_Image(const WZCallCS_And_BackToLua_Image&);
18     WZCallCS_And_BackToLua_Image& operator=(const WZCallCS_And_BackToLua_Image&);
19 
20 };


 

還記得winRT組件工程里的那個能被C#訪問的類吧,那個類里有一個setCallback 方法,實現改為如下:

 1 void WZCallCS_And_BackToCX_Image::setCall_FromCXToCS(ICallCS_And_BackCX_Image^ callback)
 2 {
 3     globalCallCS = callback;
 4 
 5     WZCallCS_And_BackToLua_Image *callCS = WZCallCS_And_BackToLua_Image::Share_GetInstance();
 6     
 7     callCS->FunCallCS_ImageCropper =  [] ()
 8     {
 9         globalCallCS->getPictureFromPhotos("");
10     };
11 }

在這里給 單例類的函數指針 一個實現,讓函數指針指向一個lambda表達式,實現內容就是訪問一個在C#里實現的方法,如此一來,在C++里需要訪問C#的時候,就獲取那個單例類,調用單例類里的函數指針即可。需要注意的時候,把lambda表達式賦給一個函數指針時,lambda表達式的函數體里是不能捕獲外部變量的,如果lambda表達式函數體里要訪問什么,就只能通過靜態變量 全局變量的方式來實現了。

需要注意的是,這部分工作必須早點做,也就是C#工程里繼承winRT組件 ICallback的那個類必須盡早(最好在mainPage 的loaded事件里做)被創建並調用winRT組件那個類的setCallback 方法,否則單例類的函數指針有可能在初始化前就被調用了。整個流程可以理解在程序啟動初始化的時候就搭好一條 C++和C# 交互的通道,主游戲邏輯想什么時候通過這條通道來訪問C#都可以。 

 

原文鏈接: http://www.cnblogs.com/zouzf/p/3971021.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM