今天在使用c++cli的时候遇到了点关于委托,callback使用的问题,简单记录一下
首先贴段简单的C#中使用System.Threading.Timer的代码.
Timer GameTimer=new Timer(new TimerCallback(this.OnGameTimer),null,0,500);
以上定时器会每隔500毫秒去调用OnGameTimer方法,OnGameTimer方法的定义如下:
void OnGameTimer(object obj){...}
基于以上代码,结合C#的使用方法,我们来写出C++CLI的使用代码.
Timer^ GameTimer=gcnew Timer(gcnew TimerCallback(this->OnGameTimer),NULL,500);
void OnGameTimer(Object^ obj){...}
很好,vs并没有提示什么语法错误,那么编译的结果呢?
Error120error C3867: 'GameServer::FrmMain::OnGameTimer': function call missing argument list; use '&GameServer::FrmMain:OnGameTimer' to create a pointer to member
按照提示,它需要一个方法函数的指针,也给了代码"&...",修改如下:
Timer^ GameTimer=gcnew Timer(gcnew TimerCallback(&FrmMain::OnGameTimer),NULL,500);
可是这次还没编译,就提示语法错误了, 编译给出的错误信息为:
Error120error C3352: 'void GameServer::FrmMain::OnGameTimer(System::Object ^)' : the specified function does not match the delegate type 'void (System::Object ^)'
这个错误提示让人实在摸不差头脑了,指定的方法函数和delegate委托不相匹配.
好吧,一番搜索,msdn示例代码 链接如下:
经过反复翻看代码好几遍,才终于弄清楚的正确的写法,如下:
Timer^ GameTimer=gcnew Timer(gcnew TimerCallback(this,&FrmMain::OnGameTimer),NULL,500);
后来才看到,其实在没有加this参数的时候,语法的错误提示是准确的,Error invalid delegate initalizer -- function does not match the delegate type.
c++cli,一直没有去系统学习,只是刚好常用c#,又懂些c++,就直接使用了,但是过程中的确经常遇到一些可能非常基础的问题,但也正是这些基础问题卡住自己.
它是c++和.net的混合,不管单独从那一个的习惯去写代码可能都会有点别扭,或许把它当作一门新的编程语言,这些奇怪的地方法也就不奇怪了. 关于它,如果想享受.net的快捷,又不愿意放弃以前c++现有的东西,或者需要和一些底层接口打交道,那么它值得去拥抱!
题外话:
最近着手在重写一个很古老的游戏服务端,目前已使用C#按照原来的c++代码重写完了GateServer,LoginServer,RoleServer,GuildServer,但是GameServer选择使用C++CLI进行重构.这份代码估计出生在1998年左右,没有使用任何设计模式,就连很多大量相同的代码都没有进行简单的封装,GameServer中的主要逻辑都写在game.cpp中,这个cpp足足有2M多,7-8w行代码揉在一起.如果GameServer也使用C#重写的话,那就无法预知工作量了.好在CLI的存在,让这份庞大杂乱的c++代码没花多少功夫就被.net化了,经测试运行进游戏一切正常. 剩下把它那稀烂的网络通信用我C#写的XKSocket替换掉,那一切就不在是问题了! XKSocket git地址: http://git.oschina.net/dreamzgj/XKSocket