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

上一篇提到工程使用 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#都可以。

时间: 2024-11-08 22:54:04

Cocos2d-x项目移植到WP8系列之三:C++和C#的交互的相关文章

Cocos2d-x项目移植到WP8系列之二:开篇

开发环境一笔带过吧,主板和CPU要支持虚拟化技术,要开启才行,装个64位win8.1系统,win8不好用,我用的是vs2012,然后装个wp8的SDK,再装个vs2012的补丁4,最后能把模拟器跑起来能上网就可以了.模拟器上网这也是个蛋疼问题,如果电脑是通过路由器DHCP自动分配IP模拟器能正常上网,但在公司里电脑是根据Mac地址绑定IP的,模拟器上不了网,这里面碰到问题的话自行谷歌吧. 公司的框架是在Cocos2d-x的框架之上稍微封装了一下,方便加上一些自己的功能,总的来说就是业务层用Lua

Cocos2d-x项目移植到WP8系列之一:前传

许久没动笔了,随想一直都有动笔的想法,但拖来拖去,归根到底还是一个懒字吧 .发现人的惰性真是太强大了,特别是在像我这种意志不够坚定的人,稍微拖一拖,一个星期,一个月,大半年,就这样都过去了,加上平时的效率也挺低的,时间都浪费得让人心痛,再和一些刚毕业一年的后辈相比,发现根本跟不上他们的步伐,无论是已掌握的技术或者学习新的东西,才猛然惊醒,甚为愧疚.针对性下药,现在强迫自己把一些要做的工作上的事情都写在一个几乎从不关闭的Excel里,每次回到桌面都能看到,还有哪些事情没有完成的,完成后就标记一下,

Cocos2d-x项目移植到WP8系列之八:CCLabelTTF显示中文不换行

在wp8平台上,CCLabeTTF显示中文不会自动换行,看了下源码,原来底层的实现是根据text的空格进行判断的,每遇到一个空格就判断是否超过label的宽度,超过就换行,但text如果是中文的话,哪来的空格给换行~~ 以下实现全部参考 http://blog.csdn.net/hopingwhite/article/details/38414917 ,整理后的代码如下: 在CCFreeTypeFont.h里的CCFreeTypeFont类添加两个方法: FT_Error addLine(con

Cocos2d-x项目移植到WP8系列之六:C#工程使用C++的DLL

此时,一些大问题都被解决后,整个工程基本能跑起来了,最后一个大问题是:业务层是用Lua开发的,底层的源码对他们是不可见的,也就是需要把我们工程生成的各种DLL.lib.winmd文件拿出来然后再搭建一个开发环境给项目组使用,要求就是,每次底层改了什么只需要把对应的生成的lib.dll.winmd文件给他们替换就行了,而他们的开发环境里工程并不需要因此而变.嗯,但我们的工程大部分都是C++的,有DLL工程,也有lib工程,还有运行时工程,如何让C#用上这些工程的生成品? 原本我们的工程结构是这样的

Cocos2d-x项目移植到WP8系列之四:文件操作

读写文件Cocos已经用fopen fwrite来做好了,这里说的主要是文件和文件夹的创建.删除.判断是否存在等. 本来打算把把这部分代码放到C#工程来做,然后通过上一篇说到的C++和C#交互的那个通道来调用的,但是wp8里很多东西都被做成异步的形式了,文件的读写操作也被设计成了异步的形式,但是在C++这边发起调用的方法是需要同步调用的,这里如何转换是一个难题,由于对task PPL 那一套不熟悉,最后没办法只能放到C++工程来做. 另外,在task里那个捕获异常也是很痛苦的一件事情——一直没研

Cocos2d-x项目移植到WP8系列之九:使用自定义shader

有时候想得到一些例如灰度图等特殊的渲染效果,就得用到自定义shader,关于shader的一些背景知识,自行谷歌,列出两篇cocos2dx里介绍shader的相关文章 http://blog.csdn.net/while0/article/details/9666829     http://blog.sina.com.cn/s/blog_aa01f7030101mdom.html cocos2dx在wp8平台不知道是不是在渲染时OpenGL要转成D3D的原因还是其他原因,不能在运行时编译链接s

Cocos2d-x项目移植到WP8系列之七:中文显示乱码

C++和C#互调时经常会带一些参数过去例如最常见的字符串,如果字符串里有中文的话,会发现传递过去后变成了乱码,这是因为两边的编码方式不一样,C#默认使用UnicodeEncoding(中文环境下是GBK?)编码,C++(Lua和cocos2d-x引擎默认编码为UTF-8)里用的是utf8编码.大概流程就是 C++的里的std::string字符串转成 C++/CX 里的 Platform::string,再传到C#里System.String ,从C#到C++的话就是反过来. Cocos其实已经

Cocos2d-x项目移植到WP8系列之五:播放MP3

这一块的细节还是不太了解,只是东凑西拼能跑起来而已 1.网上下载lamb库 生成需要的lib库,详情见 [Advanced Windows Phone Programming]在windows phone 8中录制MP3和AAC及Amr音频  第三点的前半部分,也就是生成lib那一部分,然后在CocosDenshion工程里引用那两个lib. 2.把CocosDenshion工程里的Audio.cpp里的void Audio::PreloadSoundEffect(const char* psz

【iOS与EV3混合机器人编程系列之三】编写EV3 Port Viewer 应用监测EV3端口数据

在前两篇文章中,我们对iOS与EV3混合机器人编程做了一个基本的设想,并且介绍了要完成项目所需的软硬件准备和知识准备. 那么在今天这一篇文章中,我们将直接真正开始项目实践. ==第一个项目: EV3 Port Viewer== 项目目的:在iOS设备上通过WiFi连接EV3并且读取EV3每个端口的数据. 大家可以一周之后在App Store上搜索EV3 Port Viewer,那么我已经做了一个范例App发布了,正在审核中 应用的基本使用要求:将EV3和iPhone同时连接到同一个WiFi网络中