windows下dll开发杂记<一>

在目前的项目中,发现原子业务的导出没有使用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的方式编译。

猜你喜欢

转载自blog.csdn.net/aricover/article/details/78316213