欢迎来到天天文库
浏览记录
ID:37926687
大小:440.00 KB
页数:37页
时间:2019-06-02
《C#与CC++的交互》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库。
1、http://www.2cto.com/kf/201112/113590.htmlC#与C/C++的交互warensoft中科院计算所培训中心 欢迎转载,请注明出处及作者最近在编写Warensoft3D游戏引擎,并预计明年年初发布测试版本,底层引擎使用DirectX和MONO来编写,上层的逻辑使用C#来编写,因此编写了大量C#与C++互调的代码,现在经验写出来与大家分享,并希望后来者少走弯路。C#与C++交互,总体来说可以有两种方法:·利用C++/CLI作为代理中间层·利用PInvoke实现直接调用第一种方法:实现起来比较简单直观,并且可以实现C
2、#调用C++所写的类,但是问题是MONO构架不支持C++/CLI功能,因此无法实现脱离Microsoft.NETFramework跨平台运行。第二种方法:简单的实现并不麻烦,只要添加DllImportAttribute特性即可以导入C/C++的函数,但是问题是PInvoke不能简单的实现对C++类的调用。在Warensoft3D中为了可以使用MONO实现跨平台(当然DirectX是不能跨平台的),所以使用了本方法,下面将对本方法展开详细的说明。测试平台:Windows764位,VS2010,.NET4.0注意事项:PInvoke从功能上来说,只支
3、持函数调用,在被导出的函数前面一定要添加extern"C"来指明导出函数的时候使用C语言方式编译和连接,这样保证函数定义的名字和导出的名字相同,否则如果默认按C++方式导出,那个函数的名字就会变得乱七八糟,我们的程序就无法找到入口点了。本文将说明以下几点:·互调的基本原理·基本数据类型的传递·指针的传递·函数指针的传递·结构体的传递 1.互调的基本原理首先,我们来看一个再常规不过的概念—"数据类型"我们知道在大多数的静态语言中定义变量的时候都要先指定其数据类型,所谓数据类型,都是人们强加的一个便于记忆的名称,究其本质就是指明了这个数据在内存里到
4、底是占用了几个字节,程序在运行的时候,首先找到这个数据的地址,然后再按着该类型的长度,读取相对应的内存,然后再处理。了解了前面这个事儿,所有编程语言之间进行互调就有点门道儿了。对于不同语言之间的互调,只要将该数据的指针(内存地址)传递给另一个语言,在另一个语言中根据通信协议将指针所指向的数据存储入长度对应的数据类型即可,当然要满足以下几点:1.对于像Java,.NET这样有运行时虚拟机编程语言来讲,由于虚拟机会让堆内存来回转移,因此,在进行互调的时候,要保证正在被互调的数据所在的内存一定要固定,不能被转移。2.有一些编程语言支持指针,有一些语言不
5、支持指针(如Java),这个问题并不重要,所谓指针,其实就是一个内存地址,对于32位OS的指针是一个32位整数,而对于64位机OS的指针是一个64位整数。因为大多数语言中都有整型数,所以可以利用整型来接收指针。2.基本数据类型的传递互调过程中,最基本要传递的无非是数值和字符,即:int,long,float,char等等,但是此类型非彼类型,C/C++与C#中有一些数据类型长度是不一样的,下表中列出常见数据类型的异同:C/C++C#长度shortshort2Bytesintint4Byteslong(该类型在传递的时候常常会弄混)int4Byte
6、sboolbool1Bytechar(Ascii码字符)byte1Bytewchar_t(Unicode字符,该类型与C#中的Char兼容)char2Bytesfloatfloat4Bytesdoubledouble8Bytes最容易弄混的是就是long,char两个类型,在C/C++中long和int都是4个字节,都对应着C#中的int类型,而C/C++中的char类型占一个字节,用来表示一个ASCII码字符,在C#中能够表示一个字节的是byte类型。与C#中char类型对应的应该是C/C++中的wchar_t类型,对应的是一个2字节的Unic
7、ode字符。下面通过实例来说明调用过程:第一步:建立一个C++的Win32DLL,如下图所示:这里要注意选择"Exportsymbols"导出符号。点击完成。第二步:由于项目的名称是"TestCPPDLL",因此,会自动生成TestCPPDLL.h和TestCPPDLL.cpp两个文件,.h文件是要导出内容的声明文件,为了能清楚的说明问题,我们将TestCPPDLL.h和TestCPPDLL.cpp两个文件中的所有内容都删除,然后在TestCPPDLL.h中添加如下内容:第一行代码中定义了一个名为"TESTCPPDLL_API"的宏,该宏对应的内
8、容是"__declspec(dllexport)"意思是将后面修饰的内容定义为DLL中要导出的内容。当然你也可以不使用这个宏,可以直接将
此文档下载收益归作者所有