C++ LNK2019问题

C++ LNK2019问题,c++,visual-c++,C++,Visual C++,在我的项目中尝试使用某些DLL时出现问题 详情: 我有一个叫做dll1的DLL项目;为了导出dll1内部的类(用于dll2使用),它编译得很好(使用\uu declspec(dllexport)) 我有另一个DLL项目dll2,它使用dll1的功能。我在项目属性的链接器输入中指定了*.dll1.lib文件路径,并引用了dll1*.h文件。在这一点上,一切都需要顺利进行。(我想……) 编译dll2时,我得到一个LNK2019错误,它告诉我找不到dll1中引用的某些方法。(dll1中的此方法是静态方

在我的项目中尝试使用某些DLL时出现问题

详情:

  • 我有一个叫做dll1的DLL项目;为了导出dll1内部的类(用于dll2使用),它编译得很好(使用
    \uu declspec(dllexport)
  • 我有另一个DLL项目dll2,它使用dll1的功能。我在项目属性的链接器输入中指定了*.dll1.lib文件路径,并引用了dll1*.h文件。在这一点上,一切都需要顺利进行。(我想……)
  • 编译dll2时,我得到一个LNK2019错误,它告诉我找不到dll1中引用的某些方法。(dll1中的此方法是静态方法。)

  • 为什么会出现此错误?

    对于常规静态类方法,declspec(dllexport)应该足够了,但在某些情况下(例如内联友元函数),您需要为函数提供declspec(dllexport)

    e、 g

    本文已经给出了大量发生此错误的示例。为了追踪到底发生了什么,我建议这样做:

  • 在链接器抱怨要请求名称的符号上运行
    undname
    (有关如何运行
    undname
    )的示例,请参阅
  • 运行
    dumpbin/EXPORTS
    (或使用图形)以获取由DLL1导出的所有符号的列表
  • 现在您有了链接器试图查找的符号的demangled名称,以及DLL1导出的符号列表。链接器会告诉您在列表中找不到请求的符号。这里有两个关于正在发生的事情的想法:

  • 您可以看到,DLL1在其导出列表中有demangled符号,但并不完全是链接器抱怨的损坏名称。当导出的函数与链接器期望的函数几乎相同时,就会发生这种情况。可能是您的某个地方缺少一个“const”,或者调用约定不同
  • 您可以看到,DLL1不会导出任何与链接器期望的符号类似的符号。这表明DLL1的声明中缺少一些
    \u declspec(dllexport)

  • 只是猜测:

    如果在dll2项目中包含dll1中的标题,并且在该标题中使用
    \uuuu declspec(dllexport))
    可以告诉链接器dll2也在导出这些实际上由dll2导入的类,因此缺少类定义

    所以人们通常会使用这样的定义

    #ifdef DLL1_EXPORTS
    #define DLLEXPORT __declspec(dllexport)
    #else
    #define DLLEXPORT __declspec(dllimport)
    #endif
    
    class DLLEXPORT A
    {
        //...
    
    此构造确保在dll1中使用标题时导出dll1定义,在dll2项目中使用标题时导入定义。您只需在编译DLL1时定义宏
    DLL1\u EXPORT
    dll1的项目设置通常是一个好地方


    另一种方法是有两个不同的头,一个用于构建dll1,另一个用于与dll1的库一起使用(没有任何
    \u declspec(dllexport)
    )。问题是方法签名
    voidmymethod(constmytype&)带有一个参数,我已将其转发声明为
    类MyType;然而,该定义是一个
    struct MyType{}

    如中所述,这可能会导致Visual C++的链接器问题—在我的例子中是LNK2019


    我花了一些时间来解决这个问题,也许这对将来的某个人有帮助。

    您是否在静态方法中使用了任何静态变量?作为一个想法。Ii可能有用,具体取决于使用情况。运行它,打开DLL1,检查“查看/未修饰的C++函数”,在函数和方法列表中查找函数,并检查它有完全相同的ARG数,并且它位于正确的命名空间中。当目标库是LIB而不是DLL时,是否可以做类似的事情?Dumpbin不会在静态库上运行,当我尝试在我的库上运行dependency walker时,会出现“无签名”错误。
    #ifdef DLL1_EXPORTS
    #define DLLEXPORT __declspec(dllexport)
    #else
    #define DLLEXPORT __declspec(dllimport)
    #endif
    
    class DLLEXPORT A
    {
        //...