简体   繁体   English

关于不一致的dll联动

[英]About inconsistent dll linkage

How can I remove this link warning?如何删除此链接警告? You can see code segment that causes this warning.您可以看到导致此警告的代码段。

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
    }

warning C4273: 'InitGuiCtrlsDLL': inconsistent dll linkage警告 C4273:“InitGuiCtrlsDLL”:不一致的 dll 链接

I have also export and import definitions, like:我还有导出和导入定义,例如:

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

The purpose of the preprocessor statements:预处理器语句的目的:

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

is to make sure that the header file declares the class or function as __declspec(dllexport) in the .dll where it is defined, and as __declspec(dllimport) for any other .dll that might want to use it.是确保头文件在定义它的 .dll 中将类或函数声明为 __declspec(dllexport),并为可能想要使用它的任何其他 .dll 声明为 __declspec(dllimport)。

For this to work, _GUICTRLS must be defined when compiling the exporting .dll, and not defined for any other .dll.为此,必须在编译导出 .dll 时定义 _GUICTRLS,而不是为任何其他 .dll 定义。 Generally you would expect _GUICTRLS to be defined in the project properties, under C/C++ -> Preprocessor -> Preprocessor Definitions.通常,您希望在项目属性中定义 _GUICTRLS,在 C/C++ -> Preprocessor -> Preprocessor Definitions 下。

The compiler error you are seeing usually happens because either _GUICTRLS is not defined for the project that is doing the export, or it is defined for multiple projects, usually resulting from cutting an pasting from one project to another.您看到的编译器错误通常是因为 _GUICTRLS 没有为执行导出的项目定义,或者它是为多个项目定义的,通常是由于从一个项目剪切粘贴到另一个项目。 You will also see this if _GUICTRLS is defined in a header file that is included in multiple projects.如果 _GUICTRLS 在包含在多个项目中的头文件中定义,您也会看到这一点。

There are multiple possibilities:有多种可能:

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

You use AFX_EXTENSION_MODULE.您使用 AFX_EXTENSION_MODULE。 This means that you are implementing an MFC extension DLL.这意味着您正在实现 MFC 扩展 DLL。 For such extension dlls you have to define the preprocessor _AFXEXT.对于此类扩展 dll,您必须定义预处理器 _AFXEXT。 Set this in the C++ compiler settings of your Visual C++ project在 Visual C++ 项目的 C++ 编译器设置中设置此项

see:看:

How To Use _declspec(dllexport) in an MFC Extension DLL: http://support.microsoft.com/kb/128199如何在 MFC 扩展 DLL 中使用 _declspec(dllexport): http : //support.microsoft.com/kb/128199

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

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

2) It is likely that you have a duplicated definiton/declaration. 2) 您可能有重复的定义/声明。

In addition to reading the warning message, pay attention to where it occurs if you have multiple projects as part of a workspace.除了阅读警告消息之外,如果您有多个项目作为工作区的一部分,请注意它出现的位置

I wasted time looking for a problem in my DLL which was compiling and linking correctly.我浪费时间在我的 DLL 中寻找正确编译和链接的问题。 The workspace was also building the main application and my error was that I had inadvertently included a new (DLL) source file into the build file list of the application itself .工作区也在构建主应用程序,我的错误是我无意中将一个新的 (DLL) 源文件包含到应用程序本身的构建文件列表中

The main program requires the DLL header mynewdll.h to import things but does not require the source file mynewdll.cpp.主程序需要 DLL 头文件 mynewdll.h 来导入东西,但不需要源文件 mynewdll.cpp。 (The code is brought in at run time with a DLL.) I have a habit of including header and code files into projects as a pair, and this is where I had gone wrong. (代码是在运行时通过 DLL 引入的。)我习惯于将头文件和代码文件成对包含在项目中,这就是我出错的地方。

I would have detected the error much sooner if I had been alert and noticed that the DLL project linked with no errors and it was the main program that complained!如果我保持警惕并注意到 DLL 项目链接时没有错误,并且抱怨的是主程序,我会更早地检测到错误!

My DLL source code and project was error free and it was only the way I tried to build my executable that was faulty.我的 DLL 源代码和项目没有错误,这只是我尝试构建可执行文件的方式有问题。

That warning is usually caused by a duplicate definition of a function with different use of dllimport.该警告通常是由具有不同 dllimport 用法的函数的重复定义引起的。 Are you sure you didn't do this?你确定这不是你做的?

[ CMake inconsistent dll linkage ] [CMake 不一致的 dll 链接]

I encountered the following issue + solution with the __declspec(dllexport) + __declspec(dllimport) :我在 __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") 

This was annoying because a number of sources say to use the 'set source file properties' command to get better granularity but the doc is not clear on what happens to file1.h's declares when included from a different directory... better stick with add_definitions( -DMYLIB=1 ) for now!这很烦人,因为许多消息来源说要使用“设置源文件属性”命令来获得更好的粒度,但是文档不清楚 file1.h 的声明在从不同目录包含时会发生什么情况……最好坚持使用add_definitions( -DMYLIB=1 )现在!

To catch this problem: in your Foo.cpp file:要解决这个问题:在你的 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 
{ 
};

See that you are not defining the exported symbols in a different project.请注意您没有在不同的项目中定义导出的符号。 Also clean all the intermediate files by hand and recompile.还要手动清理所有中间文件并重新编译。

In my case, error C4273 was caused by trying linking to .lib file from a DLL dynamic load tester app in Qt5 by msvc2017_64 toolchain.就我而言,错误 C4273 是由于尝试通过 msvc2017_64 工具链从 Qt5 中的 DLL 动态负载测试器应用程序链接到 .lib 文件引起的。 Removing the reference to .lib file by changing LIBS setting in .pro file have the problem solved.通过更改 .pro 文件中的 LIBS 设置来删除对 .lib 文件的引用,问题解决了。

Just by changing the order of my headers, the warning has been removed.只需更改我的标题的顺序,警告就被删除了。 I've only moved first the header containing the __declspec(dllexport).我只先移动了包含 __declspec(dllexport) 的标题。

I've also looked if there's some duplication but find none.我还查看了是否有重复但没有发现。

I'm asking myself why this works....我在问自己为什么这有效......

To elaborate the answer of damian with an example.用一个例子详细说明达米安的答案。 I read it but didn't understand at first glance.我看了,但乍一看没看懂。

You have a shared library with a source file compiled in that contains the function. In a new project you use the library and in addition you compile also the source file to use the function (I forgot that it is already in the library).您有一个共享库,其中编译了一个包含 function 的源文件。在一个新项目中,您使用该库,此外您还编译源文件以使用 function(我忘了它已经在库中)。 Within the library the functions label is exported, within the additional compiled source file the functions label is marked to be imported.在库中,函数 label 被导出,在附加编译的源文件中,函数 label 被标记为导入。 That's the conflict.这就是冲突。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM