我的观察:C++ 链接器(特别是 Visual Studio)过于重视 __declspec(dllimport),链接器仅在附加库中查找使用此指令声明的任何类/函数的定义。(忽略本地存在的定义)。我想给 __declspec(dllimport) 指令较低的优先级,以便链接器在查看其他地方之前首先考虑本地存在的定义。可以这样做吗?这也是 Windows 特定/Visual Studio 特定问题吗?如果是这样,有解决方法吗?
我在尝试在 Windows 的 Visual Studio 2015 上使用预编译的 MathGL-v2.4.2 二进制文件时遇到了这个问题。
Initial Builds 给出了许多 Linker Error 2019: unresolved external symbol __declspec(dllimport) _cdel mglGraph::mglGraph(void).... blah blah。
此外,我浏览了库代码,发现每个类和结构定义的形式如下:
class MGL_EXPORT mglGraph {
// some variables and
// Full function definitions
// (also contains some inline functions)
};
其中 MGL_EXPORT 定义为,
/* in dllexport.h the following is declared */
# ifdef mgl_EXPORTS
/* We are building this library */
# define MGL_EXPORT __declspec(dllexport)
# else
/* We are using this library */
# define MGL_EXPORT __declspec(dllimport)
# endif
另外,我查找了 libmgl.dll 导出的符号,链接器正在寻找的那些符号不存在(因此链接器自然会给出未解决的符号错误)。
综上所述,结论:链接器忽略类/函数的任何本地定义,仅查找使用 __declspec(dllimport) 指令声明的类/函数的附加库的函数定义。
更多证明:通过从完全定义的函数/类的定义中删除 MGL_EXPORT 代码编译
现在的问题是:这是特定于平台的问题吗?如果是,有解决方法吗?(因为在删除 MGL_EXPORT 指令之前仔细检查库中的每个类以确保所有函数都已完全定义是非常麻烦的)。
“我想给 __declspec(dllimport) 指令较低的优先级,以便链接器在查看其他地方之前首先考虑本地存在的定义”这非常优雅地解决了这个问题。