【问题标题】:LNK2001: unresolved external symbol when building for x64 platformLNK2001:为 x64 平台构建时无法解析的外部符号
【发布时间】:2014-09-02 05:26:16
【问题描述】:

该项目构建在 Win32 平台上,而不是 x64 平台上。

完整的错误信息: dllentry.obj : 错误 LNK2001: 无法解析的外部符号 "class CFactoryTemplate * g_Templates" (?g_Templates@@3PAVCFactoryTemplate@@A)

dllentry.cpp 可以在两个平台上编译。它包含外部声明:

extern CFactoryTemplate g_Templates[];
extern int g_cTemplates;

g_Templates[] 然后用于两个函数:

__control_entrypoint(DllExport) STDAPI DllGetClassObject(__in REFCLSID rClsID,
    __in REFIID riid, __deref_out void **pv)
{
    ...
    for (int i = 0; i < g_cTemplates; i++)
    {
        const CFactoryTemplate * pT = &g_Templates[i];
    }
}

DllInitClasses(BOOL bLoading)
{
    ...
    for (int i = 0; i < g_cTemplates; i++)
    {
        const CFactoryTemplate * pT = &g_Templates[i];
    }
}

我检查了项目设置中的所有库,似乎一切正常,使用的是 64 位版本。我应该怎么做才能为 x64 平台构建项目?

【问题讨论】:

  • g_Templates 的定义(不是声明)在哪里?是否有可能从 x64 配置中省略了该文件?
  • 要定位问题,请尝试从extern CFactoryTemplate g_Templates[]; 行中删除extern

标签: c++ visual-c++ 64-bit lnk2001


【解决方案1】:

语句extern CFactoryTemplate g_Templates[];实际上并没有定义一个名为g_Templates的数组*;它只是说明项目中某处存在一个。您实际上是在告诉编译器“不要担心您在任何地方都看不到这个东西;当需要链接时,您将能够在不同的模块中找到它。”除了这显然不是真的。我能想到的两个可能原因是(1)包含g_Templates 实际定义的文件未包含在 x64 构建配置中,以及(2)无论它在哪里,定义都被 @987654324 之类的东西包围@。

要解决这个问题,您需要找到 g_Templates 的实际定义(可能搜索“CFactoryTemplate g_Templates[”),然后确定它在 x64 构建中被省略的原因。


* 从技术上讲,它在这里被视为指针

【讨论】:

  • g_templates 定义在另一个 DirectShow 基类 sysclock.cpp 中,但仅在 #ifdef FILTER_DLL 下定义,Win32 中也不满足条件。另一个有效的定义在 myClass.cpp(我的项目的主类)'CFactoryTemplate* g_Templates=0;'其次是'int g_cTemplates = 0;'在文件的最上层,就在包含之后。 myClass.cpp 也可以自行编译。只有构建不起作用。
  • 从原始代码中我了解到您正在制作一个 dll 并且那里发生了链接错误。 myClass.cpp 是否包含在该 dll 中,还是包含在单独的 exe 项目中?
【解决方案2】:

您在对较早答案的评论中声明

另一个有效的定义在 myClass.cpp(我的主类 项目)'CFactoryTemplate * g_Templates = 0;'其次是'int g_c模板=0;'在文件的最上层,就在 包括。

您对g_Templates 的定义与其声明不一致。

声明是

extern CFactoryTemplate g_Templates[];

这将g_Templates 声明为CFactoryTemplate 的数组(大小未知)。但是你的定义

CFactoryTemplates* g_Templates = 0;

将其定义为指向CFactoryTemplate 的指针,这不是一回事。

因此,您未能提供与声明匹配的g_Templates 定义,并且错误消息是正确的。

您需要让声明和定义同意。一种方法是写

CFactoryTemplates g_Templates[1];

创建一个与声明一致的定义。 (注意,零长度数组在 C++ 中是不允许的,因此我们创建一个长度为 1 的数组并忽略其中的元素。)

另一个是将声明改为

extern CFactoryTemplates* g_Templates;

【讨论】:

  • 数组衰减为外部声明中的指针。我用 VC2012 进行了测试,在另一个模块中匹配 extern int g[]int* g 没有问题。
  • 但也许 VC 是错误的,因为进一步的测试表明,虽然链接器接受了这一点,但两个 gs 最终是不同的东西(并且调试检查器非常困惑)。
  • @dff 数组不会衰减为外部声明中的指针。它们在左值到右值的转换过程中以及在声明为函数参数时衰减为指针,但声明两者都不是。
  • 好的;但在那种情况下,dllentry.cpp(其中g_Templates被声明为数组)中的错误消息是“未解析的外部符号“class CFactoryTemplate * g_Templates””这一事实的解释是什么?
  • @dff 必须有一个指针样式的声明对 dllentry.cpp 某处可见。
猜你喜欢
  • 1970-01-01
  • 2019-01-14
  • 1970-01-01
  • 2011-05-06
  • 1970-01-01
  • 2020-04-10
  • 1970-01-01
  • 1970-01-01
  • 2013-04-11
相关资源
最近更新 更多