windows下dll开发杂记<一>

4 篇文章 0 订阅

在目前的项目中,发现原子业务的导出没有使用extern "C"关键字,而业务dll导出函数中使用了extern “C”关键字,仔细思考了下,什么情况下需要使用extern "C",一.在c++代码中调用的c的函数,需要先extern "C"声明,二.声明c++的函数为extern "C"提供给c调用,使用extern "C"告诉编译器,按照c的方式来编译接口函数,这里可以使用宏来复用

#ifdef __cplusplus
extern "C"{
#endif
  __declspec(dllexport) void* EXPORT_FUNC(char *pCA);
#ifdef __cplusplus
extern "C"{
#endif
引用上文的头文件,在c里面编译的话,(c不支持extern "C"的语法),只需要常规声明,因为c++导出的时候已经声明成了extern "C",按照c的编译方式,是可以找到该函数的,如果在c++里面编译,就会按照c的方式编译接口函数。

得出以下结论,原子业务封装只是供导出业务封装dll调用,都是c++不需要声明为extern "C',推论二,业务中间件在调用业务dll的时候,使用的c语言开发的执行逻辑,不然就不会将业务dll导出函数声明为extern "C"。

值得注意的是上文的

__declspec(dllexport) void* EXPORT_FUNC(char *pCA);

这就是另一个问题了(dll的导出函数),导出的时候是
__declspec(dllexport)

导入的时候对应的是 __declspec(dllimport),但是按照网上的资料,__declspecl(dllimport其实是可以不写的),按照msdn的说法,

不使用 __declspec(dllimport) 也能正确编译代码,但使用 __declspec(dllimport) 使编译器可以生成更好的代码。编译器之所以能够生成更好的代码,是因为它可以确定函数是否存在于 DLL 中,这使得编译器可以生成跳过间接寻址级别的代码,而这些代码通常会出现在跨 DLL 边界的函数调用中。但是,必须使用 __declspec(dllimport) 才能导入 DLL 中使用的变量

详细理解请参见http://www.cnblogs.com/lidabo/archive/2013/08/30/3291773.html的帖子

总的来说,就是可以不写__declspec(dllimport)去使用外部dll的导出函数,除非你需要用到的在另一个dll中定义的全局变量或者类中的静态成员。

而反观目前项目中的代码,在原子中导出函数是使用以下hong:

#if defined(ATOM_BUSI_EXPORTS)
#define	ATOM_BUSI_API		__declspec(dllexport)
#else
#define ATOM_BUSI_API		__declspec(dllimport)
#endif
ATOM_BUSI_EXPORTS宏,在原子项目属性中有定义,也就是作为导出__declspec,在原子的调用业务项目属性是没有添加ATOM_BUSI_EXPORTS预处理器的,也就是在编译业务的时候,是按照__declspec(dllimport)去使用的。

以上是原子与原子的关系,在业务项目中导出宏是:

#if defined(_MSC_VER)
#define EXPORT_LBM_FUNC(EXPORT_FUNC) \
	__declspec(dllexport) void* EXPORT_FUNC(char *pCA);
#else
#define EXPORT_LBM_FUNC(EXPORT_FUNC) \
	void* EXPORT_FUNC(char *pCA);
#endif

也对,毕竟中间件在调用dll的导出函数的时候,不可能会需要重新去编译一次,而是会根据配置的xml,动态地去加载具体的dll



如果在c++里面编译,就会按照c的方式编译。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值