【问题标题】:Visual Studio 2013 dll export linkage error (LNK2019/LNK1120)Visual Studio 2013 dll导出链接错误(LNK2019/LNK1120)
【发布时间】:2014-09-06 17:59:18
【问题描述】:

我知道之前有人问过类似的问题,但看起来类导出的问题与简单的函数有所不同......我已经检查了所有这些解决方案,检查了所有建议,但看起来我仍然是缺少一些东西......

发生了什么:

  • 我有一个用 Visual Studio 2013 编写的主 C++ 项目,我想添加一个带有各种实用程序的 dll 库。我创建了一个虚拟的,基本上没有功能,但它无法编译:
2> TestSvc_i.c 2>TestSvc.obj : 错误 LNK2019: 函数 _wWinMain@16 中引用的无法解析的外部符号“__declspec(dllimport) public: __thiscall CUtils::CUtils(void)” (__imp_??0CUtils@@QAE@XZ) 2>C:\Work\TestSvc_root\Debug\TestSvc.exe : 致命错误 LNK1120: 1 unresolved externals ========== 全部重建:1 成功,1 失败,0 跳过 ==========

而主项目中的代码是这样的:

extern "C" int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd)
{
    CUtils *a = new CUtils();
    delete a;

    return 1;
}

我有以下设置:

  • 使用 Visual Studio 2013 用 C++ 编写的主项目;
  • 我正在使用 Unicode 字符集,并且运行时在共享 dll 中使用;
  • _UNICODE 已定义;
  • 子系统:Windows (/SUBSYSTEM:WINDOWS);
  • 我想创建一个应在共享 dll 中使用的实用程序库。代码如下所示:

Utils.h:

#ifdef UTILS_EXPORTS
#define UTILS_API __declspec(dllexport)
#else
#define UTILS_API __declspec(dllimport)
#endif

// This class is exported from the Utils.dll
class UTILS_API CUtils {
public:
    CUtils(void);
};

Utils.cpp:

#include "stdafx.h"
#include "Utils.h"

// This is the constructor of a class that has been exported.
// see Utils.h for the class definition
CUtils::CUtils()
{
    return;
}
  • 我检查了 dll 项目设置,基本上,它们都和主项目一样;
  • UTILS_EXPORTS 是在 dll-project 中定义的,所以正常情况下,所有定义都应该有 __declspec(dllexport) (正如预期的那样,UTILS_EXPORTS 中没有定义);
  • 我有以下预处理器定义:WIN32;_DEBUG;_WINDOWS;_USRDLL;UTILS_EXPORTS;
  • dll-project 被添加为 master-project 的依赖项;
  • dll 被复制到$(SolutionDir)\Debug 下,但不在$(SolutionDir)\$(MasterProject)\Debug 下——我不知道为什么。我手动复制了,还是一样的问题;
  • 我在 Utils.dll 上运行了 DUMPBIN 实用程序,它的外观如下:
C:\Work\TestSvc_root\Debug>DUMPBIN /EXPORTS /SYMBOLS Utils.dll Microsoft (R) COFF/PE Dumper 版本 10.00.40219.01 版权所有 (C) 微软公司。版权所有。 文件 Utils.dll 的转储 文件类型:DLL 部分包含 Utils.dll 的以下导出 00000000 个特征 53C632A8 时间日期戳 2014 年 7 月 16 日星期三 10:07:04 0.00 版本 1 个序数基数 2个功能 2个名字 序号提示 RVA 名称 1 0 00011154 ??0CUtils@@QAE@XZ = @ILT+335(??0CUtils@@QAE@XZ) 2 1 000110C8 ??4CUtils@@QAEAAV0@ABV0@@Z = @ILT+195(??4CUtils@@QAEAAV0@ABV0@@Z) 概括 1000 个数据 1000 .idata 2000 .rdata 1000 .重新定位 1000 .rsrc 4000 .文本 10000 .textbss
  • 我试图“嗅探” UTILS_API 的值:
#define DO_QUOTE(X) #X #define QUOTE(X) DO_QUOTE(X) #define MY_QUOTED_VAR QUOTE(MYVARIABLE) #pragma 消息(报价(UTILS_API))

转储正确的值:当从 dll 中“使用”时,它转储 __declspec(dllexport),当从主项目中使用时,它转储 __declspec(dllimport)

那么,有什么提示吗?看起来与类导出定义/方法装饰有关......在以前的普通旧 Visual C++ 中曾经有一个“def”文件,您可以在其中映射导出的名称......但在这个新版本中,我迷路了。

谢谢!

【问题讨论】:

  • 如果作为实验,您手动将 .lib 文件添加到链接器输入列表中会发生什么?
  • Utils.dll 是否也使用 VS 2013 编译? Microsoft 不保证主要版本之间的 C++ ABI 兼容。
  • @Steve - 是的,VS2013。它们都在同一个解决方案中,并且项目依赖项设置正确(主依赖于 dll)。我检查了编译器输出,顺序是正确的。
  • 不知道对于VS2013,但是对于VS2010,将DLL项目添加为依赖项是不够的。确保您的 exe 在链接器属性中将“使用库依赖项输入”设置为“是”。
  • .lib 文件用于链接 .dll。

标签: c++ dll visual-studio-2013 linker-errors


【解决方案1】:

作为一种解决方法,您可以将 .lib 文件(在构建 .dll 期间生成)显式添加到主项目的链接器选项中的输入库列表中。

【讨论】:

    猜你喜欢
    • 2014-01-19
    • 2015-04-04
    • 2020-01-24
    • 2013-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多