为什么要在C#中调用C++的代码呢?比如我有一个C#项目要实现某种功能,同时我恰好有一个已经实现了这个功能的C++代码。我可以用C#重写一遍,当然如果工程比较大的话,用DllImport来调用C++的dll是一个更好的选择。
由于C++dll是非托管代码,我不能直接在C#工程中添加引用(会出错误提示)。命名空间System.Runtime.InteropServices提供了DllImport Attribute来动态加载非托管dll。
示例一:
C#
[DllImport("D:/UnitySocket.dll", EntryPoint="Unity_Connect")]
public static extern bool Unity_Connect(string ip, string port);
C++
extern C {
public XXX(类似FAR的一个声明值,忘了明天补上) bool Unity_Connect(string ip, string port);
}
将以上的函数声明放入一个类中,然后就可以用 类名.Unity_Connect("xxxx", "xx")来调用了。
关于C#与C++内置类型的对照,我的C++分类里的某篇文章中有详细说明(当然,是转帖,(*^__^*) 嘻嘻……)。
至于自定义类型,我目前只接触到struct类型的转换。也就是在C#中新定义一个struct,逐个字段的类型和大小都要与C++中定义的struct一致。还是写个例子吧。
示例二:
C++
struct MyDataStream
{
int length;
unsigned char cmd;
unsigned char* data;
}
C#
struct MyDataStream
{
int length;
byte cmd;
IntPtr data;
}
看起来很简单,不过复杂的地方其实在于C#与C++的类型对应。比如说:C++中字符数组是要以'/0'结尾的,C#中的string可没有结束符。这在有回调函数(C++中声明CallBack,C#中定义delegate具体函数。C++中会使用这个具体的函数)的情况时要尤其注意。
特别的,IntPtr。一般来说C++中的指针就对应C#中的IntPtr,例外情况就是char*可以对应C#中的string。但是安全的方法,就应该是对应IntPtr,然后使用Marshal类中的一箩筐静态方法来转换成C#中的具体类型。命名空间都是System.Runtime.InteropServices。
在看上面代码的时候有没有人注意到DllImport是用绝对路径写的,是否可以用相对路径呢。我查的结果,是不行滴~但是内置(找不到合适的词汇形容)dll可以,比如windows的kernel.dll。有以下几种方法(网上查的):
(待续,明天直接拷文字和代码上来)