提问人:aTom 提问时间:1/15/2022 最后编辑:aTom 更新时间:1/15/2022 访问量:311
在 Windows 上与 GameNetworkingSockets 库链接时出现“未解决的外部”错误 [重复]
Linking with GameNetworkingSockets library on Windows gives "unresolved external" error [duplicate]
问:
我有一个使用一些第三方库(GameNetworkingSockets)的CMake C++项目。
我的目标是 linux 和 windows,但我每天都在我的 linux 机器上工作,所以我不太习惯使用 msvc 构建应用程序。
今天,我的应用程序在 linux 上构建并运行良好,但在使用 MSVC 2019 在 Windows 上构建时无法链接此库:
error LNK2019: unresolved external symbol __imp_SteamNetworkingUtils
我发现了很多关于这种错误的其他问题和答案,但我没有发现任何对我有用的东西。
编辑:我读到的问题/答案之一就是这个问题,即使它非常有趣,它也没有帮助我解决我的问题,因为它太笼统了。
我想静态链接到这个库,我在我的 CMake 项目中通过在我的文件中使用它来管理它:CMakeLists.txt
find_package(GameNetworkingSockets 1.2.0 REQUIRED)
target_include_directories(my_project PRIVATE ${GameNetworkingSockets_INCLUDE_DIR})
target_link_libraries(my_project ${GameNetworkingSockets_LIBRARY})
我制作了一个模块文件,在其中我告诉 CMake 查找或查找必须事先构建的库,并查找以找到正确的标头包含目录:FindGameNetworkingSockets.cmake
libGameNetworkingSockets_s.a
GameNetworkingSockets_s.lib
steam/isteamnetworkingutils.h
# Try to find GameNetworkingSockets lib
# Check for SDK_ROOT
if( NOT SDK_ROOT )
message(FATAL_ERROR "You have to set SDK_ROOT before calling find_package().")
endif()
# Set search paths
set( _GameNetworkingSockets_HEADER_SEARCH_DIR "${SDK_ROOT}/include/GameNetworkingSockets" )
set( _GameNetworkingSockets_LIB_SEARCH_DIR "${SDK_ROOT}/lib" )
# Search for the headers
FIND_PATH(GameNetworkingSockets_INCLUDE_DIR "steam/isteamnetworkingutils.h" PATHS "${_GameNetworkingSockets_HEADER_SEARCH_DIR}")
# Search for the library
FIND_LIBRARY(GameNetworkingSockets_LIBRARY NAMES libGameNetworkingSockets_s.a GameNetworkingSockets_s.lib PATHS ${_GameNetworkingSockets_LIB_SEARCH_DIR} NO_DEFAULT_PATH)
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GameNetworkingSockets DEFAULT_MSG GameNetworkingSockets_LIBRARY GameNetworkingSockets_INCLUDE_DIR)
message(STATUS "GameNetworkingSockets library was found : ${GameNetworkingSockets_LIBRARY}")
message(STATUS "GameNetworkingSockets header was found in : ${GameNetworkingSockets_INCLUDE_DIR}")
在linux或windows中运行CMake时,我可以看到库及其头目录被找到:
linux
-- GameNetworkingSockets library was found : /sdk/debug/lib/libGameNetworkingSockets_s.a
-- GameNetworkingSockets header was found in : /sdk/debug/include/GameNetworkingSockets
windows
-- GameNetworkingSockets library was found : C:/sdk/debug/lib/GameNetworkingSockets_s.lib
-- GameNetworkingSockets header was found in : C:/sdk/debug/include/GameNetworkingSockets
然后,在 linux 上构建时(使用 Ninja 生成器):
[...]
[245/245 4.5/sec] Linking CXX executable my_project
通过查看可执行文件,我可以看到许多与库相关的符号,即使名称被篡改:nm my_project | grep SteamNetworkingUtils
0000000000c39ee0 T SteamNetworkingUtils
000000000143c278 b _ZGVZ20SteamNetworkingUtilsE7s_utils
0000000000c537a0 t _ZN21ISteamNetworkingUtils20SetConfigValueStructERK28SteamNetworkingConfigValue_t27ESteamNetworkingConfigScopel
0000000000c34cd0 T _ZN21ISteamNetworkingUtilsD1Ev
0000000000c34cd0 t _ZN21ISteamNetworkingUtilsD2Ev
0000000000c39d30 T _ZN25SteamNetworkingSocketsLib21CSteamNetworkingUtils13GetTimeSecureEv
0000000000c39790 T _ZN25SteamNetworkingSocketsLib21CSteamNetworkingUtils14GetConfigValueE27ESteamNetworkingConfigValue27ESteamNetworkingConfigScopelP30ESteamNetworkingConfigDataTypePvPm
0000000000c394c0 T _ZN25SteamNetworkingSocketsLib21CSteamNetworkingUtils14SetConfigValueE27ESteamNetworkingConfigValue27ESteamNetworkingConfigScopel30ESteamNetworkingConfigDataTypePKv
0000000000c393c0 T _ZN25SteamNetworkingSocketsLib21CSteamNetworkingUtils15AllocateMessageEi
0000000000c393e0 T _ZN25SteamNetworkingSocketsLib21CSteamNetworkingUtils17GetLocalTimestampEv
0000000000c39a10 T _ZN25SteamNetworkingSocketsLib21CSteamNetworkingUtils18GetConfigValueInfoE27ESteamNetworkingConfigValuePPKcP30ESteamNetworkingConfigDataTypeP27ESteamNetworkingConfigScopePS1_
0000000000c39bc0 T _ZN25SteamNetworkingSocketsLib21CSteamNetworkingUtils19GetFirstConfigValueEv
0000000000c39400 T _ZN25SteamNetworkingSocketsLib21CSteamNetworkingUtils22SetDebugOutputFunctionE38ESteamNetworkingSocketsDebugOutputTypePFvS1_PKcE
0000000000c39c30 T _ZN25SteamNetworkingSocketsLib21CSteamNetworkingUtils30SteamNetworkingIPAddr_ToStringERK21SteamNetworkingIPAddrPcmb
0000000000c39ca0 T _ZN25SteamNetworkingSocketsLib21CSteamNetworkingUtils32SteamNetworkingIdentity_ToStringERK23SteamNetworkingIdentityPcm
0000000000c39c70 T _ZN25SteamNetworkingSocketsLib21CSteamNetworkingUtils33SteamNetworkingIPAddr_ParseStringEP21SteamNetworkingIPAddrPKc
0000000000c39cd0 T _ZN25SteamNetworkingSocketsLib21CSteamNetworkingUtils35SteamNetworkingIdentity_ParseStringEP23SteamNetworkingIdentityPKc
0000000000c39d10 T _ZN25SteamNetworkingSocketsLib21CSteamNetworkingUtils8GetAppIDEv
0000000000c39390 T _ZN25SteamNetworkingSocketsLib21CSteamNetworkingUtilsD0Ev
0000000000c39370 t _ZN25SteamNetworkingSocketsLib21CSteamNetworkingUtilsD1Ev
0000000000c39370 T _ZN25SteamNetworkingSocketsLib21CSteamNetworkingUtilsD2Ev
0000000000c35520 t _ZN25SteamNetworkingSocketsLib23CSteamNetworkingSocketsC1EPNS_21CSteamNetworkingUtilsE
0000000000c35520 T _ZN25SteamNetworkingSocketsLib23CSteamNetworkingSocketsC2EPNS_21CSteamNetworkingUtilsE
0000000001302548 D _ZTVN25SteamNetworkingSocketsLib21CSteamNetworkingUtilsE
000000000130e418 d _ZZ20SteamNetworkingUtilsE7s_utils
但是,当使用 MSVC 2019 在 Windows 下构建时,仍然是忍者生成器(对不起,我的 Windows 操作系统是法语的,所以这些是法语错误消息):
FAILED: my_project.exe
cmd.exe /C "cd . && "C:\Program Files\CMake\bin\cmake.exe" -E vs_link_exe --intdir=CMakeFiles\my_project.dir --rc=C:\PROGRA~2\WI3CF2~1\10\bin\100190~1.0\x64\rc.exe --mt=C:\PROGRA~2\WI3CF2~1\10\bin\100190~1.0\x64\mt.exe --manifests -- C:\PROGRA~2\MICROS~2\2019\PROFES~1\VC\Tools\MSVC\1428~1.299\bin\Hostx64\x64\link.exe /nologo @CMakeFiles\my_project.rsp /out:my_project.exe /implib:my_project.lib /pdb:my_project.pdb /version:0.0 /machine:x64 /debug /INCREMENTAL /subsystem:console && cd ."
LINK Pass 1: command "C:\PROGRA~2\MICROS~2\2019\PROFES~1\VC\Tools\MSVC\1428~1.299\bin\Hostx64\x64\link.exe /nologo @CMakeFiles\my_project.rsp /out:my_project.exe /implib:my_project.lib /pdb:my_project.pdb /version:0.0 /machine:x64 /debug /INCREMENTAL /subsystem:console /MANIFEST /MANIFESTFILE:CMakeFiles\my_project.dir/intermediate.manifest CMakeFiles\my_project.dir/manifest.res" failed (exit code 1120) with the following output:
servernetworkmanager.cpp.obj : error LNK2019: symbole externe non résolu __imp_SteamNetworkingUtils référencé dans la fonction "public: bool __cdecl ServerNetworkManager::InitSteamDatagramConnectionSockets(void)" (?InitSteamDatagramConnectionSockets@ServerNetworkManager@@QEAA_NXZ)
servernetworkmanager.cpp.obj : error LNK2019: symbole externe non résolu __imp_SteamNetworkingSockets référencé dans la fonction "public: bool __cdecl ServerNetworkManager::InitSteamDatagramConnectionSockets(void)" (?InitSteamDatagramConnectionSockets@ServerNetworkManager@@QEAA_NXZ)
servernetworkmanager.cpp.obj : error LNK2019: symbole externe non résolu __imp_GameNetworkingSockets_Init référencé dans la fonction "public: bool __cdecl ServerNetworkManager::InitSteamDatagramConnectionSockets(void)" (?InitSteamDatagramConnectionSockets@ServerNetworkManager@@QEAA_NXZ)
servernetworkmanager.cpp.obj : error LNK2019: symbole externe non résolu __imp_GameNetworkingSockets_Kill référencé dans la fonction "public: void __cdecl ServerNetworkManager::ShutdownSteamDatagramConnectionSockets(void)" (?ShutdownSteamDatagramConnectionSockets@ServerNetworkManager@@QEAAXXZ)
my_project.exe : fatal error LNK1120: 4 externes non résolus
这就是我被困住的地方,我不知道该何去何从。我从CLI构建所有内容,但是我尝试在Visual Studio中打开CMake项目,并且遇到了相同的错误。我不知道如何从 MSVC 链接器获取更多信息。我什至不知道错误是出在我的项目中,还是出在我构建项目依赖项的方式上(GameNetworkingSocket、它自己的依赖项以及我正在使用的其他东西,所有这些都构建并安装在我的文件夹中)。任何帮助都值得赞赏^^sdk
答:
在 Windows 上,静态链接的符号名称与动态链接的符号名称不同。
未解析符号中的前缀表示,您与静态库链接,但标头配置为动态链接:https://stackoverflow.com/a/5159395/3440745__imp
默认情况下,项目 GameNetworkingSockets 将其标头视为动态链接。要将其切换到“静态模式”,请添加编译定义:STEAMNETWORKINGSOCKETS_STATIC_LINK
target_compile_definitions(my_project PUBLIC STEAMNETWORKINGSOCKETS_STATIC_LINK)
实际上,项目 GameNetworkingSockets 的安装提供了现成的配置脚本,因此无需编写“Find”脚本即可使用:find_package
find_package(GameNetworkingSockets 1.2.0 REQUIRED)
# For dynamic linking use target without '_s' suffix.
target_link_libraries(my_project PUBLIC GameNetworkingSockets::GameNetworkingSockets_s)
评论