__declspec(dllexport) 导出符号解决链接失败问题
清泛原创
error LNK2019: 无法解析的外部符号 "public: __thiscall CBtt::CBtt(void)" (??0CBtt@@QAE@XZ),该符号在函数 "protected: __thiscall COwnerView::COwnerView(void)" (??0COwnerView@@IAE@XZ) 中被引用
error LNK2019: 无法解析的外部符号 "public: __thiscall CBtt::~CBtt(void)" (??1CBtt@@QAE@XZ),该符号在函数 "public: void * __thiscall CBtt::`scalar deleting destructor'(unsigned int)" (??_GCBtt@@QAEPAXI@Z) 中被引用
1>../outdir/Debug/xxx.exe : fatal error LNK1120: 2 个无法解析的外部命令
的编译错误。
原因是引用的dll中的函数没有导出导致,可以用Depends打开dll查看验证,使用如下的宏申明解决:
#ifdef _EXPORTING
#define API_DECLSPEC __declspec(dllexport)
#elif defined USE_LIB
#define API_DECLSPEC
#else
#define API_DECLSPEC __declspec(dllimport)
#endif
...
class API_DECLSPEC CBtt
{
public:
CBtt(void);
~CBtt(void);
};
注意:宏必须放在 class 与对象名中间,不可放在class的前面。
再来个跨平台版本:
#ifdef WIN32
#ifdef XXX_EXPORTS
#define XXX_API __declspace(dllexport)
#elif defined USE_LIB
#define XXX_API
#else
#define XXX_API __declspace(dllimport)
#endif
#define XXX_LOCAL
#else
#ifdef XXX_EXPORTS
#define XXX_API __attribute__ ((visibility("default")))
#elif defined USE_LIB
#define XXX_API
#else
#define XXX_API
#endif
#define XXX_LOCAL __attribute__ ((visibility("hidden")))
#endif
...
class XXX_API Object {
...
};
Linux与Windows导出不同的地方在于:1、Windows默认不导出,需要导出的话必须申明;Linux默认全部导出,但是很多时候默认的编译选项都加上了 -fvisibility=hidden 指定不导出,然后使用上面的宏,自定义导出,与Windows就类似了。
特别注意:
以上这个导出、导入的方式仅针对动态库,而静态库无需任何申明,宏全部替换成空即可。