C#中使用DllImport调用C++dll

时间:2022-08-31 09:02:26

 为什么要在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。有以下几种方法(网上查的):

(待续,明天直接拷文字和代码上来)