C#调用C++的dll

来源:互联网 发布:淘宝卖家推广平台 编辑:程序博客网 时间:2024/06/05 20:48

C#调用C++的dll使用如下方式:

        [DllImport("DllSecond")]        static extern int Multiply(int factorA,int factorB);

C#调用C++的dll声明时必须使用extern修饰符,这样做的目的是告诉编译器该函数是在外部实现的。声明时必须同时使用static修饰符。在C++的工程或代码中也需要做一些处理,这样才能调用成功。目前有两种方式:
第一种方式是在编写C++代码时添加

extern "C" _declspec(dllexport)

在C++中可以通过_declspec(dllexport)将函数导出为Dll中供其它程序调用,例如:

_declspec(dllexport) int add(int a, int b);

在这种方式下,如果调用该dll的是一个C++程序(通一个编译器的版本)是没有问题的。但是,如果调用该dll是一个其他语言的程序,则会出错。究其原因,是因为在C++中存在函数的重载,允许函数重名,因此在编译器生成dll的时候,为了区别重名的程序,会将其进行一定算法进行名称转换。因此,我们直接通过函数名add是无法找到该函数的,从而导致调用失败。为了解决这一问题,我们往往在函数前面再加一个extern “C”,使用C方式的函数命名规则。

extern "C" _declspec(dllexport) int add(int a, int b);

第二种方式是使用模块定义文件(def文件),将要导出的函数放在def文件中。因此需要在C++项目中添加一个.def文件.
示例如下:

LIBRARY EXPORTS         Multiply

一般C/C++默认的调用方式是__cdecl,这种方式下需要调用方对函数清栈。如果对外提供api共其它非C++程序使用时,调用方会无法清栈而出错(C#会直接报函数声明不匹配的错误)。因此,对外提供api时还应该将接口声明为__stdcall,让api函数自己清栈.在C#调用中CallingConvention设置为Cdecl也可以。
C++:

void PrintMsg(const char* msg){    printf("%s\n", msg);    return;}

C#调用:

 [DllImport("DllForTest.dll",CallingConvention= CallingConvention.Cdecl)]        static extern void PrintMsg(string msg);

参考:
http://www.cnblogs.com/TianFang/archive/2013/05/04/3059073.html

0 0
原创粉丝点击