9

我正在尝试从 Crysis Wars SDK 的源代码构建一个 DLL,并且过去在 Visual Studio 的早期版本(即 2005、2008 和 2010)上已成功完成此操作。我的具体问题是这样的:

Error   4   error LNK2019: unresolved external symbol "struct CTypeInfo const & __cdecl
TypeInfo<char>(char *)" (??$TypeInfo@D@@YAABUCTypeInfo@@PAD@Z) referenced in function 
"void __cdecl SwapEndian<char>(char *,unsigned int)" (??$SwapEndian@D@@YAXPADI@Z)   
G:\Noctis\Mods\Noctis\Code\GameCVars.obj    GameDll

我试图清理 Visual Studio 中的代码并在可能会工作的情况下重建它,但这并没有改变任何东西。

我在这里遗漏了什么,还是从 C++03 更改为 C++11,这意味着如果不恢复到旧版本的 C++,这段代码就不再可编译?

我已经在 64 位和 32 位的 Visual Studio 2010 上成功编译了这段代码,所以它一定是与将项目迁移到 Visual Studio 2015 相关的一些问题。

在 2012、2013 和 2015 版本的 Visual Studio 上编译会重现此错误,但不会重现 2010,因此似乎在 C++11 中引入了触发此问题的更改。

我究竟做错了什么?

阅读mem-fun 的答案不是 std 的成员,可能只是我需要包含一个我不需要包含在早期版本的 Visual Studio 中的标准库。如果这是真的,我需要哪个图书馆#include

我还创建了一个 GitHub 存储库,其中仅包含SDK 提供的原始未修改代码,用于测试目的(如果我自己打错了,这里似乎不是这种情况,但我把链接放在这里它可能会有所帮助)。

如果重要的话,我在 Windows 10 Professional x64 上使用 Visual Studio 2015 企业版。

4

1 回答 1

4

错误是什么意思?

错误消息提示经典的“已声明但未定义”场景。

TypeInfo<char>(char*)在 TypeInfo.h 中声明(通过一些宏)并AutoTypeInfo.cpp在项目 CryCommon 中声明。

通常,您只需确保正确构建 CryCommon 项目并正确链接到最终的 GameDll 项目,仅此而已。

但事实证明,CryCommon 项目已经很久没有构建了——它引用了许多其他 Crytek 库等。所以问题一定是现在需要这些TypeInfo<>定义,而以前不需要。

什么是引用TypeInfo<>代码?

在您的项目中,它CmdHelp()在 Aurora/Code/GameCVars.cpp 中起作用,正是这一行:

nRead = gEnv->pCryPak->FRead( buf, BUFSZ, f );

FRead()方法的实现在 CryCommon/ICryPak.h 中:

template<class T>
size_t FRead(T *data, size_t elems, FILE *handle, bool bSwap = true)
{
    size_t count = FReadRaw(data, sizeof(T), elems, handle);
    if (bSwap)
        SwapEndian(data, count);
    return count;
}

如您所见,如果bSwap为 true(默认值),SwapEndian()则在此处调用。

为什么以前没有表现出来?

也许编译器确实表现不同。

或者,更有可能的是,您之前一直将项目编译为Release。整个字节交换功能仅在大端系统(并且您的目标很可能不是其中之一)或在调试期间启用 - 然后字节实际上被交换两次以测试相关代码(请参阅 CryCommon/Endian.h) .

可以做些什么来修复它?

你现在有几个选择:

  • 继续编译为仅发布版本(可能和以前一样)。也许你永远不会在调试器中调试代码。

  • 只需将代码中的交换调用FRead()注释掉即可。无论如何,您都在使用它来加载文本文件,没有必要交换字符。

  • ...


FWIW,我必须做的其他事情才能使您的代码编译:

  • 查看“Broken”之前的早期提交
  • 加载 Mods\Aurora\Code\Aurora.sln
  • 删除不存在的 .vcprojx 项目
  • 再次添加所有 3 个 .vcproj 文件,让它们转换为 VS2015 的文件
  • 对于 GameDll 项目,添加预处理器定义_SILENCE_STDEXT_HASH_DEPRECATION_WARNING
  • 对于 GameDll 项目,设置启用 C++ 异常处理/EHsc
  • 注释掉上面的代码
于 2016-02-29T22:48:13.890 回答