利用C++/CLI 封装Native C++ 提升.NET web game性能
利用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#代码在性能方面的对比
- C++/CLI封装Native C++,并被C#调用
为了方便团队开发,我们通常要将C++代码编译成DLL,以方便.NET开发人员调用,因此,我们首先来编写一个Native C++的类,并编译成DLL。过程如下:
- 在VS2008的VC++项目模板中,选择Win32项目中的 Win32 Project,并命名为NativeCPPDLL,如下图所示:
- 选择将其编译成DLL,如下图所示:
- 在项目中添加一个名为NativeCPP的类,基类结构如下图所示:
- 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();
}
- 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函数是游戏里常用的数据增长公式
}
}
- 编译代码。
- 在解决方案中添加一个C++/CLI的类库,将命名为CPPWrapper如下图所示:
- 为CPPWrapper添加刚才编译好的DLL项目的引用,如下图所示,在该项目上点击右键,选择"Reference":
- 在弹出的对话框中选择Add New Reference,如下图所示:
- 在Projects里选择刚才建立的NativeCPPDLL项目。如下图所示:
- 在CPPWrapper里添加一个头文件,内容和名称都"NativeCPP.h"一样。
- 在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 ();
}
- 在C++/CLI的项目属性里,将Common Language Runtime Support设置为Common Language Runtime Support(/clr),否则的话,将无法使用非托管的Native C++。
- 现在可以建立一个C#的项目了,只要添加CPPWrapper的引用,就可以像调用C#写的DLL一样来调用C++/CLI写的类了,如下图所示:
- 如何你用的是64位的操作系统的话,直接调用会出错,这时要配置一个C#项目的编译选择,将编译的目标平台设置成"X86"。(请千万别把它读成"叉儿八六",你是专业计算机人员,应该说的专业点,它叫"艾克思八六")。如下图所示:
- 前面对如何利用C++/CLI封装原生C++代码,并被C#所调用作了一些说明,下面通过数据对比来说明这样做的意义。
- 实验说明:
该实验将进行如下几组测试
编号 |
说明 |
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函数。
- 代码略
- 测试环境
- 测试结果(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、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性能相关推荐
- 利用 C++ Interop 封装 ISO C++ 对象, 供其他 .Net 语言使用
2019独角兽企业重金招聘Python工程师标准>>> .Net BCL 支持两种互操作技术,模块 级重用 P/Invoke 和组件级重用COM 互操作, C++/CLI 除了支持以 ...
- 函数模板案例_利用函数模板封装一个排序的函数,可以对不同数据类型数组进行排序 排序规则从大到小,排序算法为选择排序 分别利用char数组和int数组进行测试
案例描述: 利用函数模板封装一个排序的函数,可以对不同数据类型数组进行排序 排序规则从大到小,排序算法为选择排序 分别利用char数组和int数组进行测试 #include <iostream& ...
- 利用Spring框架封装的JavaMail现实同步或异步邮件发送
利用Spring框架封装的JavaMail现实同步或异步邮件发送 作者:张纪豪 J2EE简单地讲是在JDK上扩展了各类应用的标准规范,邮件处理便是其中一个重要的应用.它既然是规范,那么我们就可以通过J ...
- 利用ES6-Promise()方法封装原始jsonp实现跨域请求公用方法(告别使用JQuery封装好的jsonp)
在项目中,经常需要用到jsonp实现跨域请求,假如使用JQuery封装好的jsonp方法,是很容易实现的,缺点:需要引入JQuery库. $.ajax({url : './package.json', ...
- C++CLR类库封装Native类库并用C#调用
1.创建Native类库 新建项目->其他语言->Visual C++->Win32控制台应用程序->DLL 添加头文件 添加源文件 选择生成路径生成dll 2.CLR类库封装 ...
- axios怎么封装,才能提升效率?
大家好,我是若川.今天分享一篇axios封装的文章.学习源码系列.面试.年度总结.JS基础系列. 作为前端开发者,每个项目基本都需要和后台交互,目前比较流行的ajax库就是axios了,当然也有同学选 ...
- altium designer利用向导画封装库详解
altium designer利用向导画封装库详解 由于前人已经将方法总结得很好.在此引用前人的成果,以防时间一长就忘掉了.首先对前辈的工作表示感谢. altium designer6.9为例画一个B ...
- 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 用于排查的工 ...
- 网站互点工具_如何利用关键词互点互刷提升网站关键词排名?
最近老是点击一个网站进去看,几天后发现关键词排名提高了,就在想是不是通过点击网站可以提高关键词排名了?网上不是有好多朋友都在寻求关键词互点,而且要求点击某篇文章,并且要在页面停留多少分钟,说这样才以提 ...
最新文章
- 如何让Spring Boot 的配置 “动” 起来?
- Sql字符串分组Split函数的两种实现方法
- 【Boost】boost库中thread多线程详解3——细说lock_guard
- 关于程序员的脑筋急转弯(附答案)
- classcastexception异常_优雅的异常处理
- php5.6代码转换7.1,通过PHP5.6源代码在WINDOWS 7下进行编译生成(最详细步骤)
- Nginx + uWSGI + Flask + Vhost
- 集成产品开发(IPD)初探
- 机器学习入门——numpy与matplotlib的使用简介
- python while true循环_python学习——while True的用法
- IDEA构建Spring源码
- 关于计算机Excel中的试题,2015年职称计算机考试EXCEL练习试题及答案
- JavaWeb(二)框架搭建篇
- UE for Mac 破解方法
- 英语对话关于计算机,有关电脑的一些英语对话
- 打开office报错提示向程序发送命令时出现问题
- VS 错误: cout 不明确
- JAVA实现手机短信验证码在指定有效的时间里校验
- 讲座报名|美团无人机团队技术分享:大规模、高精度激光SLAM
- 乡村田园风的美食账号为何能在强者如云的美食号中走出一条路?