利用C++/CLI 封装Native C++ 提升.NET web game性能

这段时间在做新项目的技术论证,其基本想法就是利用Flex调用远程WCF以及发送Socket请求,来实现远程通信,WCF负责实时性要求不高的操作,如聊天,邮件,交易,买卖等,而Socket的目的是提供实时战斗的服务。

无论是WCF,还是Socket,都会提供不少的游戏逻辑,当然,大家心里都有数,与C++相比C#在纯数值运算上慢的太多,但是提到语法简洁性,MS的数据访问组件支持,IDE的智能感知VC又相形见绌。

虽然C++/CLI不能够满足上面的各种要求,但是它却可以Native C++和C#的Adapter,来保证程序的优质性。本文的目的有两点:

         如何利用C++/CLI封装Native C++,并被C#调用

         被封装过的Native C++代码与C#代码在性能方面的对比

  1. C++/CLI封装Native C++,并被C#调用

    为了方便团队开发,我们通常要将C++代码编译成DLL,以方便.NET开发人员调用,因此,我们首先来编写一个Native C++的类,并编译成DLL。过程如下:

    1. 在VS2008的VC++项目模板中,选择Win32项目中的 Win32 Project,并命名为NativeCPPDLL,如下图所示:

    2. 选择将其编译成DLL,如下图所示:

    3. 在项目中添加一个名为NativeCPP的类,基类结构如下图所示:

    4. NativeCPP的头文件(NativeCPP.h)代码如下:

      #pragma once

      #include "math.h"

      #ifndef GoWin_DLL_CLASS_EXPORTS

      //该类可导出

      #define GoWin_DLL_CLASS __declspec(dllexport)

      #else

      //该类可导入

      #define GoWin_DLL_CLASS __declspec(dllimport)

      #endif

      class GoWin_DLL_CLASS NativeCPP

      {

      public:

      NativeCPP(void);

      ~NativeCPP(void);

      void Compute1();

      void Compute2();

      }

    5. NativeCPP的CPP文件(NativeCPP.cpp)的代码如下所示:

      #include "StdAfx.h"

      #include "NativeCPP.h"

      NativeCPP::NativeCPP(void)

      {

      }

      NativeCPP::~NativeCPP(void)

      {

      }

      void NativeCPP::Compute1 ()

      {

      for(int i=0;i<100000;i++)

      {

      for(int j=0;j<i;j++)

      {

      }

      }

      }

      void NativeCPP::Compute2 ()

      {

      for(int i=0;i< 30000000;i++)

      {

      pow(1.05,i);//pow函数是游戏里常用的数据增长公式

      }

      }

  1. 编译代码。
  2. 在解决方案中添加一个C++/CLI的类库,将命名为CPPWrapper如下图所示:

  3. 为CPPWrapper添加刚才编译好的DLL项目的引用,如下图所示,在该项目上点击右键,选择"Reference":

  4. 在弹出的对话框中选择Add New Reference,如下图所示:

  5. 在Projects里选择刚才建立的NativeCPPDLL项目。如下图所示:

  6. 在CPPWrapper里添加一个头文件,内容和名称都"NativeCPP.h"一样。
  7. 在CPPWrapper里添加一个名为NativeCPPWrapper的托管类,如下图所示:

    该类的结构与NativeCPP中的类结构完全一样,但是要在类中定义一个从DLL导入的Native C++类的指针,.h文件中的代码如下所示:

    #pragma once

    #include "NativeCPP.h"

    #define GoWin_DLL_CLASS_EXPORTS

    public ref class NativeCPPWrapper

    {

    private:

    NativeCPP*nativeCPP;//native c++类的指针

    public:

    NativeCPPWrapper(void);

    public:

    void Compute1();

    void Compute2();

    };

该类的CPP文件,完成就是对Native C++类的接口转换,其代码如下所示:

#include "StdAfx.h"

#include "NativeCPPWrapper.h"

NativeCPPWrapper::NativeCPPWrapper(void)

{

this->nativeCPP =new NativeCPP();

}

void NativeCPPWrapper::Compute1()

{

this->nativeCPP ->Compute1 ();

}

void NativeCPPWrapper::Compute2()

{

this->nativeCPP ->Compute2 ();

}

  1. 在C++/CLI的项目属性里,将Common Language Runtime Support设置为Common Language Runtime Support(/clr),否则的话,将无法使用非托管的Native C++。

  2. 现在可以建立一个C#的项目了,只要添加CPPWrapper的引用,就可以像调用C#写的DLL一样来调用C++/CLI写的类了,如下图所示:

  3. 如何你用的是64位的操作系统的话,直接调用会出错,这时要配置一个C#项目的编译选择,将编译的目标平台设置成"X86"。(请千万别把它读成"叉儿八六",你是专业计算机人员,应该说的专业点,它叫"艾克思八六")。如下图所示:

  1. 前面对如何利用C++/CLI封装原生C++代码,并被C#所调用作了一些说明,下面通过数据对比来说明这样做的意义。
    1. 实验说明:

该实验将进行如下几组测试

编号

说明

1

利用MFC调用NativeCPP 的DLL,并分别测试NativeCpp中Compute1()以及Compute2()两个函数所需要的时间

2

利用C# WinForm调用NativeCPPWrapper(C++/CLI)来间接访问NativeCPP类中的Compute1()以及Compute2()两个函数,并检测所需要的时间。

3

利用C# WinForm直接调用C#编写的相同功能的Compute1()以及Compute2()两个函数,并检测所需要的时间。

说明:Compute1()里只有循环,Compute2()里包括了一个pow函数。

  1. 代码略
  2. 测试环境

  3. 测试结果(Debug版本)

编号

操作

时间

1

MFC 调用NativeCPP::Compute1()

14s

2

MFC调用NativeCPP::Compute2()

9s

3

C#调用NativeCPPWrapper::Compute1()

14s

4

C#调用NativeCPPWrapper::Compute2()

9s

5

C#调用C#写的Compute1()

19s

6

C#调用C#写的Compute2()

3s

  1. 结论

通过1、2、3、4的数据,不难发现,利用C++/CLI封装过的Native C++在性能上基本没有什么损失(但是一定要在操作密集中的代码中封装,而不是调用密集型的代码)。1、3、5三组数据可说明,在单纯的循环上,C#要比C++慢很多。

在debug模式下大量使用Pow函数的时候.net framework里提供的Math.Pow,要远远快于math.h中的pow函数,实验结果中几乎差了三倍!如果改成Release模式,C++中两函数的操作时间基本上都为0,当然C#的速度也有明显提高,但是要远远慢于C++。

转载于:https://www.cnblogs.com/warensoft/archive/2010/03/07/1680290.html

利用C++/CLI 封装Native C++ 提升.NET web game性能相关推荐

  1. 利用 C++ Interop 封装 ISO C++ 对象, 供其他 .Net 语言使用

    2019独角兽企业重金招聘Python工程师标准>>> .Net BCL 支持两种互操作技术,模块 级重用 P/Invoke 和组件级重用COM 互操作, C++/CLI 除了支持以 ...

  2. 函数模板案例_利用函数模板封装一个排序的函数,可以对不同数据类型数组进行排序 排序规则从大到小,排序算法为选择排序 分别利用char数组和int数组进行测试

    案例描述: 利用函数模板封装一个排序的函数,可以对不同数据类型数组进行排序 排序规则从大到小,排序算法为选择排序 分别利用char数组和int数组进行测试 #include <iostream& ...

  3. 利用Spring框架封装的JavaMail现实同步或异步邮件发送

    利用Spring框架封装的JavaMail现实同步或异步邮件发送 作者:张纪豪 J2EE简单地讲是在JDK上扩展了各类应用的标准规范,邮件处理便是其中一个重要的应用.它既然是规范,那么我们就可以通过J ...

  4. 利用ES6-Promise()方法封装原始jsonp实现跨域请求公用方法(告别使用JQuery封装好的jsonp)

    在项目中,经常需要用到jsonp实现跨域请求,假如使用JQuery封装好的jsonp方法,是很容易实现的,缺点:需要引入JQuery库. $.ajax({url : './package.json', ...

  5. C++CLR类库封装Native类库并用C#调用

    1.创建Native类库 新建项目->其他语言->Visual C++->Win32控制台应用程序->DLL 添加头文件 添加源文件 选择生成路径生成dll 2.CLR类库封装 ...

  6. axios怎么封装,才能提升效率?

    大家好,我是若川.今天分享一篇axios封装的文章.学习源码系列.面试.年度总结.JS基础系列. 作为前端开发者,每个项目基本都需要和后台交互,目前比较流行的ajax库就是axios了,当然也有同学选 ...

  7. altium designer利用向导画封装库详解

    altium designer利用向导画封装库详解 由于前人已经将方法总结得很好.在此引用前人的成果,以防时间一长就忘掉了.首先对前辈的工作表示感谢. altium designer6.9为例画一个B ...

  8. Win下基于通用C运行库UCRT的部署 - 及 {C++/CLI封装的托管dll被C#工程调用时出现未加载(could not load file or assembly)错误排查}

    目录 C++/CLI封装的托管dll被C#工程调用时出现未加载(could not load file or assembly)错误排查及基于通用C运行库UCRT的部署 0 问题分析 1 用于排查的工 ...

  9. 网站互点工具_如何利用关键词互点互刷提升网站关键词排名?

    最近老是点击一个网站进去看,几天后发现关键词排名提高了,就在想是不是通过点击网站可以提高关键词排名了?网上不是有好多朋友都在寻求关键词互点,而且要求点击某篇文章,并且要在页面停留多少分钟,说这样才以提 ...

最新文章

  1. 如何让Spring Boot 的配置 “动” 起来?
  2. Sql字符串分组Split函数的两种实现方法
  3. 【Boost】boost库中thread多线程详解3——细说lock_guard
  4. 关于程序员的脑筋急转弯(附答案)
  5. classcastexception异常_优雅的异常处理
  6. php5.6代码转换7.1,通过PHP5.6源代码在WINDOWS 7下进行编译生成(最详细步骤)
  7. Nginx + uWSGI + Flask + Vhost
  8. 集成产品开发(IPD)初探
  9. 机器学习入门——numpy与matplotlib的使用简介
  10. python while true循环_python学习——while True的用法
  11. IDEA构建Spring源码
  12. 关于计算机Excel中的试题,2015年职称计算机考试EXCEL练习试题及答案
  13. JavaWeb(二)框架搭建篇
  14. UE for Mac 破解方法
  15. 英语对话关于计算机,有关电脑的一些英语对话
  16. 打开office报错提示向程序发送命令时出现问题
  17. VS 错误: cout 不明确
  18. JAVA实现手机短信验证码在指定有效的时间里校验
  19. 讲座报名|美团无人机团队技术分享:大规模、高精度激光SLAM
  20. 乡村田园风的美食账号为何能在强者如云的美食号中走出一条路?

热门文章

  1. 计算机网络可以分为点对点网络,计算机网络第1章习题答案
  2. 退出登入的php怎么写,php中退出登录怎么写
  3. 【蓝桥杯】蓝桥杯日期类问题总结
  4. 蓝桥2017真题剪邮票
  5. ffplay播放器移植VC的工程:ffplay for MFC
  6. Linux C语言解析 yaml,c – 用yaml cpp解析yaml
  7. MySQL命令行格式化输出
  8. 【特别版】计算机哲学对学习生活借鉴的几个例子
  9. PHP留言并展示_留言页面展示功能
  10. xyplorer保存设置失败_将windows右键菜单添加到XYplorer