链接Windows API

问题描述 投票:0回答:1

我正在使用ITK 库。当我使用此库编写示例程序时,出现以下链接器错误。正如我们所看到的,这些所有“未解析”的符号都是 Windows API 函数,这些 Windows API 函数是由 ITK 库而不是我的程序使用的。

Error   1   error LNK2019: unresolved external symbol _SnmpUtilVarBindFree@4 referenced in function "int __cdecl gdcm::GetMacAddrSys(unsigned char *)" (?GetMacAddrSys@gdcm@@YAHPAE@Z)  C:\Projects\sampleProject\bin\itkgdcm.lib(gdcmUtil.obj)
Error   2   error LNK2019: unresolved external symbol _SnmpUtilOidNCmp@12 referenced in function "int __cdecl gdcm::GetMacAddrSys(unsigned char *)" (?GetMacAddrSys@gdcm@@YAHPAE@Z) C:\Projects\sampleProject\bin\itkgdcm.lib(gdcmUtil.obj)
Error   3   error LNK2019: unresolved external symbol _SnmpUtilOidCpy@8 referenced in function "int __cdecl gdcm::GetMacAddrSys(unsigned char *)" (?GetMacAddrSys@gdcm@@YAHPAE@Z)   C:\Projects\sampleProject\bin\itkgdcm.lib(gdcmUtil.obj)
Error   4   error LNK2019: unresolved external symbol _WSAStartup@8 referenced in function "int __cdecl gdcm::GetMacAddrSys(unsigned char *)" (?GetMacAddrSys@gdcm@@YAHPAE@Z)   C:\Projects\sampleProject\bin\itkgdcm.lib(gdcmUtil.obj)
Error   5   error LNK2019: unresolved external symbol __imp__UuidCreate@4 referenced in function "private: static bool __cdecl gdcm::Util::GenerateUUID(unsigned char *)" (?GenerateUUID@Util@gdcm@@CA_NPAE@Z)  C:\Projects\sampleProject\bin\itkgdcm.lib(gdcmUtil.obj)
Error   6   error LNK2019: unresolved external symbol _gethostbyname@4 referenced in function "private: static class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl gdcm::Util::GetIPAddress(void)" (?GetIPAddress@Util@gdcm@@CA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ)  C:\Projects\sampleProject\bin\itkgdcm.lib(gdcmUtil.obj)
Error   7   error LNK2019: unresolved external symbol _gethostname@8 referenced in function "private: static class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl gdcm::Util::GetIPAddress(void)" (?GetIPAddress@Util@gdcm@@CA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ)    C:\Projects\sampleProject\bin\itkgdcm.lib(gdcmUtil.obj)
Error   8   error LNK2019: unresolved external symbol _WSACleanup@0 referenced in function "private: static class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl gdcm::Util::GetIPAddress(void)" (?GetIPAddress@Util@gdcm@@CA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ) C:\Projects\sampleProject\bin\itkgdcm.lib(gdcmUtil.obj)

这些错误在我心中并没有引起什么疑问。对于其中一些问题,我认为我知道答案,但我是否正确或错误需要确认。

  1. 这些Windows API函数在gdcmUtil.cpp中使用(因为它说gdcmUtil.obj)。因此,编译器将 gdcmUtil.cpp 编译为(例如)gdcmUtil.asm,而汇编器将其汇编为 gdcmUtil.obj。因为在编译库时我们没有生成任何 exe 文件。这些 *.obj 文件不与任何其他 *.obj 文件链接。因此,Windows API 符号仍然是该模块的外部符号,因此尚未解决。对吗?

  2. 谁在生成 *.LIB 文件?我的意思是编译器正在生成 *.s 文件,汇编器正在生成 *.obj 文件,并且我们没有使用链接器。那么,我们从哪里得到 *.lib 文件呢?谁将所有 *.obj 文件打包到 *.lib 文件中?

  3. Windows API应用程序(用C编写并使用Windows API的程序)是如何编译的?我的意思是,因为它是一个独立的应用程序,这些 WIN32 API 符号是如何解析的?假设我已经编写了这样的程序,谁能告诉我成功构建应用程序需要什么?

  4. 我知道Windows API是在kernel32.dll、gdi32.dll、user32.dll中实现的(这可能会依次导入一些其他dll,例如用于网络API的wsock32.dll等),但问题是如何在C 程序中的 Windows API 函数。我的意思是如何动态链接这些 DLL

  5. 在我寻求链接器错误问题的答案时。我发现我必须将 wsock32.lib(对于 WinSock 1.1)或 ws2_32.lib(对于 WinSock 2)或 snmpapi.lib 添加到链接器输入。

    1. Windows API 从什么时候开始静态链接?
    2. 从什么时候 Windows API 开始以静态库(*.lib 文件)形式提供?
    3. 在哪个目录中可以找到所有这些奇怪的 *.lib 文件?
  6. 现在,除了将 *.lib 文件添加到链接器输入文件之外,还有其他解决方案吗?因为当我使用一些新的 ITK 库函数时,我会收到一个新的链接器错误。我必须通过 Google 查找此特定符号(窗口 api 函数)所属的 *.lib 文件,然后将该 *.lib 文件添加到我的链接器输入中。这让我疯狂!有什么靠谱的办法吗?

winapi dll linker
1个回答
3
投票
  1. 是的,没错。
  2. 谁在生成 what .lib 文件?静态库通常由
    lib
    实用程序生成。
    dll
    的库通常由链接器生成。
  3. 您可以通过链接正确的库来解析 Windows 符号。
  4. 再次,通过链接适当的库(例如,您提到的三个 DLL 的 kernel32.lib、gdi32.lib 和 user32.lib)。
  5. 它不是静态链接的。您链接到图书馆。对于 DLL 的库(例如上面列出的库),链接器使用它将记录嵌入到可执行文件中,告诉加载程序使用哪个 DLL 来解析这些符号。 .lib 文件位于 SDK 安装位置的
    lib
    子目录中(通常类似于
    C:\Program Files\Microsoft SDKs\Windows\v6.0A
    )。通常 SDK 安装程序会在必要时添加这些文件,因此您在从命令链接时无需显式指定该目录线或在 Visual Studio 中。
  6. 有一些,尽管它们是否真的是一种改进还有待商榷。一种可能性是使用编译指示告诉链接器使用特定的库:

    #pragma comment(lib, "ws2_32.lib")

如果标头使用依赖于特定库的函数,这在标头中特别有用。

© www.soinside.com 2019 - 2024. All rights reserved.