关于不一致的dll链接

时间:2010-04-07 12:51:41

标签: c++ dll warnings linkage

如何删除此链接警告?您可以看到导致此警告的代码段。

static AFX_EXTENSION_MODULE GuiCtrlsDLL = { NULL, NULL };
//bla bla
// Exported DLL initialization is run in context of running application
    extern "C" void WINAPI InitGuiCtrlsDLL()
    {
     // create a new CDynLinkLibrary for this app
      new CDynLinkLibrary(GuiCtrlsDLL);
     // nothing more to do
    }

警告C4273:'InitGuiCtrlsDLL':不一致 t dll link

我还有导出和导入定义,例如:

#ifdef _GUICTRLS
   #define GUI_CTRLS_EXPORT __declspec(dllexport)
#else
   #define GUI_CTRLS_EXPORT  __declspec(dllimport)
#endif

7 个答案:

答案 0 :(得分:39)

预处理程序语句的目的:

#ifdef _GUICTRLS 
   #define GUI_CTRLS_EXPORT __declspec(dllexport) 
#else 
   #define GUI_CTRLS_EXPORT  __declspec(dllimport) 
#endif 

是确保头文件在定义它的.dll中将类或函数声明为__declspec(dllexport),并将__declspec(dllimport)声明为可能想要使用它的任何其他.dll。

为此,必须在编译导出.dll时定义_GUICTRLS,而不为任何其他.dll定义_GUICTRLS。通常,您希望在项目属性中定义_GUICTRLS,在C / C ++下 - >预处理器 - >预处理器定义。

您看到的编译器错误通常会发生,因为没有为正在执行导出的项目定义_GUICTRLS,或者为多个项目定义了_GUICTRLS,这通常是因为从一个项目切换到另一个项目。如果在包含在多个项目中的头文件中定义_GUICTRLS,您也会看到这一点。

答案 1 :(得分:18)

有多种可能性:

1)static AFX_EXTENSION_MODULE GuiCtrlsDLL = { NULL, NULL };

您使用AFX_EXTENSION_MODULE。这意味着您正在实现MFC扩展DLL。对于此类扩展dll,您必须定义预处理器_AFXEXT。在Visual C ++项目的C ++编译器设置中设置它

请参阅:

如何在MFC扩展DLL中使用_declspec(dllexport):http://support.microsoft.com/kb/128199

(目前我不能发布超过1个链接,因为我的声誉小于10.我稍后会添加2个更重要的链接。所以如果这是解决方案,请将其标记为加快流程的答案;))< / p>

正如所承诺的,这里有两个链接:

AFX_EXTENSION_MODULE结构:http://msdn.microsoft.com/en-us/library/sxfyk0zk.aspx

TN033:MFC的DLL版本:http://msdn.microsoft.com/en-us/library/hw85e4bb.aspx

2)您可能有重复的定义/声明。

答案 2 :(得分:2)

该警告通常是由不同使用dllimport的函数的重复定义引起的。你确定你没有这样做吗?

答案 3 :(得分:1)

[CMake不一致的dll链接]

我使用__declspec(dllexport)+ __declspec(dllimport)遇到了以下问题+解决方案:

# # #CMakeLists.txt
add_defintions(-DMYLIB=1)
# The above was the solution...
#    (MYLIB is used in the standard ifdef + define MYLIB_EXPORT syntax)
#  Below: seems to get overruled by other directory's headers: 
set_source_files_properties(  file1.h  file2.h  COMPILE_FLAGS "-DMYLIB=1") 

这很烦人,因为许多消息来源都说要使用“设置源文件属性”。命令以获得更好的粒度,但是文档不清楚file1.h在从不同的目录中包含什么时声明...现在更好地坚持add_definitions( -DMYLIB=1 )

要解决此问题:在您的Foo.cpp文件中:

#include "export.h"
#if defined(MYLIB)
#if defined(OTHERLIB)
  static_assert(0,"error, check your definitions!");
  // OTHER depends on MY; can't have both of these flags being set!
#endif
#endif
struct  OTHER_EXPORT  foo 
{ 
};

答案 4 :(得分:1)

如果您有多个项目作为工作区的一部分,除了阅读警告消息外,请注意它发生的位置

我浪费时间在我的DLL中寻找正确编译和链接的问题。工作区也在构建主应用程序, 我的错误是我无意中将新的(DLL)源文件包含到应用程序本身的构建文件列表中

主程序需要DLL头mynewdll.h来导入东西,但不需要源文件mynewdll.cpp。 (代码是在运行时使用DLL引入的。)我习惯将头文件和代码文件作为一对包含在项目中,这就是我出错的地方。

如果我一直警觉并且发现DLL项目没有错误链接并且它是抱怨的主程序,我会更快地检测到错误!

我的DLL源代码和项目没有错误,这只是我尝试构建可执行文件的方式。

答案 5 :(得分:0)

请注意,您没有在其他项目中定义导出的符号。也可以手动清理所有中间文件并重新编译。

答案 6 :(得分:0)

对于我来说,错误C4273是由尝试通过msvc2017_64工具链从Qt5中的DLL动态负载测试器应用程序链接到.lib文件引起的。通过更改.pro文件中的LIBS设置删除对.lib文件的引用已解决了问题。