简体   繁体   English

使用 MSVC 的 Linker 中的“LNK2005 DLLMain 已定义...”冲突

[英]"LNK2005 DLLMain already defined ..." conflict in Linker using MSVC

I have a C++ project which up to now had no problems compiling and linking but due to a recent computer crash I had to re-install everything including Visual Studio and all my VCPKG packages.我有一个 C++ 项目,到目前为止编译和链接都没有问题,但由于最近的计算机崩溃,我不得不重新安装所有东西,包括 Visual Studio 和我所有的 VCPKG 包。 (I am using VS 2022 Preview, and was before.) (我使用的是 VS 2022 预览版,之前是这样。)

My project uses many STATICALLY linked libraries including Intel's TBB and Armadillo (which depends on OPENBLAS, amongst other things).我的项目使用了许多静态链接的库,包括英特尔的 TBB 和 Armadillo(这取决于 OPENBLAS 等)。 However, it should be noted that OPENBLAS and TBB both still require a DLL to be linked even if the project uses static linking.但是,需要注意的是,即使项目使用 static 链接,OPENBLAS 和 TBB 仍然需要链接 DLL。

Now I am compiling the same project with the same Project Properties that worked before and am constantly getting the LNK2005 error stating that:现在我正在用以前工作的相同项目属性编译同一个项目,并且不断收到 LNK2005 错误,指出:

DllMain already defined in openblas.lib(memory.c.obj)..... tbb_debug.lib(tbb_main.obj) DllMain 已经在 openblas.lib(memory.c.obj) 中定义...... tbb_debug.lib(tbb_main.obj)

If I switch the linking order all that happens is the error changes to如果我切换链接顺序,所有发生的都是错误更改为

DllMain already defined in tbb_debug.lib(tbb_main.obj).... openblas.lib(memory.c.obj) DllMain 已在 tbb_debug.lib(tbb_main.obj).... openblas.lib(memory.c.obj) 中定义

[Note: It is the same problem linking in Release and Debug configurations.] [注意:在发布和调试配置中链接是同样的问题。]

Now what I cannot figure is why this even happens.现在我想不通的是为什么会发生这种情况。 Surely it is normal for projects to depend on more than one imported DLL.当然,项目依赖多个进口 DLL 是正常的。 And it is quite normal for DLLs to export their DllMain entry point function. DLL 导出它们的 DllMain 入口点 function 是很正常的。

With the PC crash I have been forced to upgrade everything to the absolute latest versions and I wonder if this has introduced the problem somewhere.由于 PC 崩溃,我被迫将所有内容升级到绝对最新版本,我想知道这是否在某个地方引入了问题。

Is this a bug in MSVC that considers two DllMain functions from two different DLLs as conflicting?这是 MSVC 中的一个错误,它认为来自两个不同 DLL 的两个 DllMain 函数存在冲突?

If this is a real conflict, can someone explain to me how this does not happen more often to people building large projects using third party DLLs?如果这是一个真正的冲突,有人可以向我解释一下,使用第三方 DLL 构建大型项目的人不会经常发生这种情况吗?

I have tried everything including a fresh install of VCPKG but nothing helps.我已经尝试了所有方法,包括全新安装 VCPKG,但没有任何帮助。

The only option I have found to get this to complete the linking is to use the /FORCE:MULTIPLE option, which I really do not like as it could be creating a flawed executable.我发现完成链接的唯一选择是使用 /FORCE:MULTIPLE 选项,我真的不喜欢它,因为它可能会创建有缺陷的可执行文件。

Any advice here would really be appreciated.这里的任何建议将不胜感激。

OK - I figured out a solution that does not require /FORCE:MULTIPLE好的 - 我想出了一个不需要 /FORCE:MULTIPLE 的解决方案

It seems either both or one of OPENBLAS and TBB cannot be built statically even though both packages compile fine with the triplet x64-windows-static .似乎 OPENBLAS 和 TBB 两者或其中之一都无法静态构建,即使这两个包都可以使用三元组x64-windows-static良好编译。

What I did was create my own triplet called x64-windows-mixed to both statically and dynamically link the libraries.我所做的是创建自己的名为x64-windows-mixed的三元组,以静态和动态链接库。 Default is static and it uses dynamic only for TBB and OPENBLAS.默认为 static,它仅对 TBB 和 OPENBLAS 使用动态。

Here is the code for the new triplet I created:这是我创建的新三元组的代码:

set(VCPKG_TARGET_ARCHITECTURE x64)
set(VCPKG_CRT_LINKAGE static)
set(VCPKG_LIBRARY_LINKAGE static)

if (${PORT} MATCHES "tbb")
   set(VCPKG_LIBRARY_LINKAGE dynamic)
endif()

if (${PORT} MATCHES "openblas")
   set(VCPKG_LIBRARY_LINKAGE dynamic)
endif()

After creating this "mixed" triplet, you will need to vcpkg install xxxx:x64-windows-mixed all the libraries you need to use with it and define the new triplet in the VCPKG section of the Project Properties page in the创建这个“混合”三元组后,您需要vcpkg install xxxx:x64-windows-mixed所有需要使用的库,并在项目属性页面的 VCPKG 部分定义新的三元组

This allows the compilation of the statically compiled project but also dynamically links OPENBLAS and TBB.这允许编译静态编译的项目,但也可以动态链接 OPENBLAS 和 TBB。

Refer to the VCPKG documentation https://vcpkg.readthedocs.io/en/latest/users/triplets/#per-port-customization请参阅 VCPKG 文档https://vcpkg.readthedocs.io/en/latest/users/triplets/#per-port-customization

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

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