代码之家  ›  专栏  ›  技术社区  ›  photo_tom

VS2008未链接到库中的所有函数

  •  0
  • photo_tom  · 技术社区  · 15 年前

    我们的项目是一个基于VS2008的使用Boost和Qt的项目。然而,今天我们有一个新的链接问题,没有任何意义。

    在连接过程中

    • 对于程序A,我们的静态库Foobar正在查找到8个成员函数中5个函数的链接。
    • 对于程序FoobarUnitTest,Foobar链接和运行的一切都很好。

    当我说链接器找到一些成员函数时,我所做的是使用/VERBOSE选项进行链接。然后我去检查结果构建日志.htm我可以看到链接器从库中找到一些函数的位置。链接器错误为“error LNK2019:unresolved external”

    关于去哪儿找有什么建议吗?

    1 回复  |  直到 15 年前
        1
  •  0
  •   John Dibling    15 年前

    对于这样一个模糊不清的问题,很难给出任何有意义的建议,但这里有几件事值得注意。链接器报告“unresolved externals”,当头文件说有一个名为“x::y()”的函数,但在lib文件中找不到该函数时。请记住,这是假设您实际上已经实现了所讨论的功能。然而,不管问题最终是什么,它都将是“你告诉我有一个名为x::y()的函数,但是你没有实现一个名为x::y()的函数”的变形

    所以,第0步是确保你已经实现了这些函数。好吧,假设你有。

    declspec(__dllexport) 对图书馆实施中的职能进行界定,以及 declspec(__dllimport) 在客户端调用函数。我为此使用宏:

    MyFancyLib.h公司:

    #ifndef MYLIB_API
    #  define MYLIB_API (declspec(__dllimport))
    #endif
    
    MYLIB_API void DoIt();
    

    MyFancyLib.CPP公司:

    // this should be moved to stdafx.h or something sufficiently low-level
    #define MYLIB_API (declspec(__dllexport))
    
    MYLIB_API void DoIt()
    {
      // magic happens
    }
    

    第二步:确保你 在实现中正确命名事物。我最常见的错误之一是声明类或命名空间的成员函数,比如 namespace Foo { void DoIt(); }; ,然后忘记在实现中完全限定类或命名空间。如果您从未在实现中调用该函数,那么链接器可能永远也找不到它。

    namespace lib
    {
      MILIB_API void DoIt();
    };
    

    MyLib.cpp文件:

    MYLIB_API void DoIt()
    {
      // magic happens
    };
    

    这将生成一个未解析的外部文件。CPP应如下所示:

    MYLIB_API void mylib::DoIt()
    {
      // magic
    }
    

    第三步:确保你链接到所有你需要链接的东西。这看起来更像第0步或第1步,但是假设你已经链接到了你想要的所有东西 认为 你需要,这一步很难。查看链接器抱怨的名称,对它们进行一些修饰,并搜索库中实现这些函数的代码。您可能会发现它们是从一个项目中导出的,而不是从您认为导出它们的项目中导出的。