我有一个C++项目,到目前为止,它的编译和链接没有问题,但由于最近的一次计算机崩溃,我不得不重新安装所有东西,包括Visual Studio和我所有的VCPKG包。(我正在使用VS 2022预览版,以前也是。(
我的项目使用了许多静态链接库,包括英特尔的TBB和Armadillo(这取决于OPENBLAS等(。但是,需要注意的是,即使项目使用静态链接,OPENBLAS和TBB仍然需要链接DLL。
现在,我正在用以前工作过的相同项目属性编译同一个项目,并不断收到LNK2005错误,说明:
DllMain已在openblas.lib(memory.c.obj(中定义……tbb_debug.lib(tbb_main.obj
如果我切换链接顺序,所发生的只是错误变为
DllMain已在tbb_debug.lib(tbb_main.obj(…openblas.lib(memory.c.obj
[注意:这与Release和Debug配置中的链接问题相同。]
现在我想不出为什么会发生这种事。当然,项目依赖于多个导入的DLL是正常的。DLL导出它们的DllMain入口点函数是很正常的。
随着电脑崩溃,我不得不将所有东西升级到绝对最新的版本,我想知道这是否在某个地方引入了问题。
这是MSVC中认为来自两个不同DLL的两个DllMain函数冲突的错误吗?
如果这是一个真正的冲突,有人能向我解释一下,在使用第三方DLL构建大型项目的人中,这种情况不会更频繁吗?
我尝试了所有的东西,包括新安装的VCPKG,但没有任何帮助。
我找到的唯一一个完成链接的选项是使用/FORCE:MULTIPLE选项,我真的不喜欢这个选项,因为它可能会创建一个有缺陷的可执行文件。
如有任何建议,我们将不胜感激。
OK-我找到了一个不需要/FORCE的解决方案:MULTIPLE
看起来OPENBLAS和TBB中的两个或一个都不能静态构建,即使这两个包都使用三元组x64-windows-static
编译得很好。
我所做的是创建自己的三元组x64-windows-mixed
,以静态和动态地链接库。默认为静态,并且仅对TBB和OPENBLAS使用动态。
以下是我创建的新三元组的代码:
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()
在创建这个";混合的";三元组,您需要vcpkg install xxxx:x64-windows-mixed
所有需要与之一起使用的库,并在的项目属性页面的VCPKG部分中定义新的三元组
这允许编译静态编译的项目,但也可以动态链接OPENBLAS和TBB。
请参阅VCPKG文档https://vcpkg.readthedocs.io/en/latest/users/triplets/#per-端口定制