使用def文件简化dll导出
2015-11-20 14:57
246 查看
在C++中,我们可以通过 __declspec(dllexport) 将函数导出为Dll中供其它程序使用,例如:
_declspec(dllexport)
int add(int a,
int b);
在这种方式下,如果调用该dll的是一个c++程序(同一个编译器的版本)是没有问题的。但是,如果调用该dll是一个其它语言的程序(如C#、VB),则会出错。究其原因,是因为在C++中存在函数的重载,允许函数重名,因此在编译器生成dll的时候,为了区别重名的程序,会将其进行一定算法进行名称转换。例如,对于前面的add函数,实际的函数名称是如下形式。
因此,我们直接通过函数名add是无法找到该函数的,从而导致调用失败。为了解决这一问题,我们往往在函数前面再加一个extern
"C",使用C方式的函数命名规则。
extern
"C"
_declspec(dllexport)
int add(int a,
int b);
这样函数的名称就成add了。
这样,我们就需要在每一个函数签名加上"extern
"C"
_declspec(dllexport)"这一长串声明。如果需要导出的函数较多则显得非常繁琐,也非常难看。为了简化这一过程,MS引入了def文件方便我们操作。
使用Def文件比较简单,只需要在项目中添加一个def文件,然后把我们要导出的函数放在def文件中即可。
Def文件的简单示例如下:
LIBRARY
EXPORTS
add
最后记得在链接器选项中选中使用的def文件(默认情况下,添加def文件时会自动加上该选项,无需手动更改)。
这样,我们的函数无需加那一堆前缀,仍然可以使用默认的int add(int a,
int b);形式,但导出后的方式依然是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
_declspec(dllexport)
int add(int a,
int b);
在这种方式下,如果调用该dll的是一个c++程序(同一个编译器的版本)是没有问题的。但是,如果调用该dll是一个其它语言的程序(如C#、VB),则会出错。究其原因,是因为在C++中存在函数的重载,允许函数重名,因此在编译器生成dll的时候,为了区别重名的程序,会将其进行一定算法进行名称转换。例如,对于前面的add函数,实际的函数名称是如下形式。
因此,我们直接通过函数名add是无法找到该函数的,从而导致调用失败。为了解决这一问题,我们往往在函数前面再加一个extern
"C",使用C方式的函数命名规则。
extern
"C"
_declspec(dllexport)
int add(int a,
int b);
这样函数的名称就成add了。
这样,我们就需要在每一个函数签名加上"extern
"C"
_declspec(dllexport)"这一长串声明。如果需要导出的函数较多则显得非常繁琐,也非常难看。为了简化这一过程,MS引入了def文件方便我们操作。
使用Def文件比较简单,只需要在项目中添加一个def文件,然后把我们要导出的函数放在def文件中即可。
Def文件的简单示例如下:
LIBRARY
EXPORTS
add
最后记得在链接器选项中选中使用的def文件(默认情况下,添加def文件时会自动加上该选项,无需手动更改)。
这样,我们的函数无需加那一堆前缀,仍然可以使用默认的int add(int a,
int b);形式,但导出后的方式依然是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
相关文章推荐
- UITabBarController
- ab和jmeter进行GET/POST压力测试的使用心得和比较
- App图标(App Icons)
- Android 4K高清图片解码显示(2)BitmapFactory常用Bitmap的解码方法
- Android内存管理
- 1006. 换个格式输出整数 (15)
- Java中String类浅谈
- u盘导致文件编码的改变
- 3d打印舵机零件
- Node.js以数据流的方式处理查询数据
- Android React Native自定义组件的流程
- Apple 企业开发者账号&邓白氏码申请记录
- Node.js使用iis管理器中session丢失处理
- 1005. 继续(3n+1)猜想 (25)
- 【面试】Service与Activity如何实现通信
- Android高仿qq登陆界面
- 1044 状态压缩·一
- Java通过配置文件连接Mysql和Oracle数据库
- DataContractJsonSerializer进行Json的序列化和反序列化
- linux ssh 登录报hosts错误