使用def文件简化dll导出

在C++中,我们可以通过__declspec(dllexport)函数导出为Dll中供其它程序使用,例如:

_declspec(dllexport)intadd(inta,intb);

在这种方式下,如果调用该dll的是一个c++程序(同一个编译器的版本)是没有问题的。但是,如果调用该dll是一个其它语言的程序(如C#、VB),则会出错。究其原因,是因为在C++中存在函数的重载,允许函数重名,因此在编译器生成dll的时候,为了区别重名的程序,会将其进行一定算法进行名称转换。例如,对于前面的add函数,实际的函数名称是如下形式。

因此,我们直接通过函数名add是无法找到该函数的,从而导致调用失败。为了解决这一问题,我们往往在函数前面再加一个extern"C"使用C方式的函数命名规则。

extern"C"_declspec(dllexport)intadd(inta,intb);

这样函数名称就成add了。

这样,我们就需要在每一个函数签名加上"extern"C"_declspec(dllexport)"这一长串声明。如果需要导出的函数较多则显得非常繁琐,也非常难看。为了简化这一过程,MS引入了def文件方便我们操作。

使用Def文件比较简单,只需要在项目中添加一个def文件,然后把我们要导出的函数放在def文件中即可。

Def文件的简单示例如下:

LIBRARY
EXPORTS
add

最后记得在链接器选项中选中使用的def文件认情况下,添加def文件时会自动加上该选项,无需手动更改)。

这样,我们的函数无需加那一堆前缀,仍然可以使用认的intadd(inta,intb);形式,但导出后的方式然是C形式的函数定义。

最后指得一提的是,一般C/C++认的调用方式是__cdecl,这种方式下需要调用方对函数清栈。如果对外提供api共其它非C++程序使用时,调用方会无法清栈而出错(C#会直接报函数声明不匹配的错误)。因此,对外提供api时还应该将接口声明为__stdcall,让api函数自己清栈。这也是Windows API前面都加上一个WINAPI的宏的原因。

def文件还有许多其它的高级用法,要进一步了解的话,可以参看一下MS的官方文档:http://msdn.microsoft.com/zh-cn/library/28d6s79h(v=vs.80).aspx

相关文章

Windows2012R2备用域控搭建 前置操作 域控主域控的主dns:自...
主域控角色迁移和夺取(转载) 转载自:http://yupeizhi.blo...
Windows2012R2 NTP时间同步 Windows2012R2里没有了internet时...
Windows注册表操作基础代码 Windows下对注册表进行操作使用的...
黑客常用WinAPI函数整理之前的博客写了很多关于Windows编程的...
一个简单的Windows Socket可复用框架说起网络编程,无非是建...