C++ ';TypeInfo<;char>;(字符*)和#x27;isn';t定义但在C和x2B之前工作+;11; 发生了什么变化,如何修复错误?

C++ ';TypeInfo<;char>;(字符*)和#x27;isn';t定义但在C和x2B之前工作+;11; 发生了什么变化,如何修复错误?,c++,c++11,visual-studio-2015,c++03,C++,C++11,Visual Studio 2015,C++03,我正在尝试从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)

我正在尝试从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
错误4错误LNK2019:未解析的外部符号“struct CTypeInfo const&\uuu cdecl
类型信息(字符*)“(???”$TypeInfo@D@@YaabutTypeInfo@@PAD@Z)在函数中引用
“void uu cdecl SwapEndian(char*,unsigned int)”($SwapEndian@D@@YAXPADI@Z)   
G:\Noctis\Mods\Noctis\Code\GameCVars.obj GameDll
我曾尝试在VisualStudio中清理代码并重建它,但这并没有改变任何事情

<>我在这里漏掉了什么东西,或者是从C++ 03到C++ 11的东西,这意味着这个代码不再编译,而不返回到一个更旧的C++版本? 我已经在VisualStudio2010上成功地以64位和32位编译了这段代码,因此将项目迁移到VisualStudio2015时一定会遇到一些问题

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

我做错了什么

阅读的答案,可能只是我需要包含一个标准库,而我不需要在早期版本的VisualStudio中包含它。 如果这是真的,我需要包含哪个库

为了测试的目的,我也做了(如果我自己犯了一个打字错误,这里似乎不是这样,但我把链接放在这里,因为它可能会有帮助)

如果有必要,我正在Windows 10 Professional x64上使用Visual Studio 2015企业版。

错误是什么意思? 错误消息提示出现典型的“已声明但未定义”场景

TypeInfo(char*)
在TypeInfo.h中声明(通过一些宏),并在project.common中的
AutoTypeInfo.cpp
中声明

通常,您只需确保CryCommon项目正确构建,并正确链接到最终的GameDll项目中,就这样

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

什么是引用
TypeInfo
代码? 在您的项目中,Aurora/code/GameCVars.cpp中的函数
CmdHelp()
,正是这一行:

nRead = gEnv->pCryPak->FRead( buf, BUFSZ, f );
FRead()
方法的实现在crycomon/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;
}
模板
size\u t FRead(t*数据,size\t元素,文件*句柄,bool-bSwap=true)
{
大小\u t计数=FReadRaw(数据、大小f(t)、元素、句柄);
如果(bSwap)
SwapEndian(数据、计数);
返回计数;
}
如您所见,如果
bSwap
为true(默认值),
SwapEndian()
将在此处调用

为什么这以前没有表现出来? 也许编译器的行为确实有所不同

或者,更可能的是,您以前总是将项目编译为发行版。整个字节交换功能仅在big-endian系统上启用(您的目标很可能不是其中之一)或在调试期间启用-然后字节实际上交换两次以测试相关代码(请参阅crycomon/endian.h)

可以做些什么来修复它? 您现在有几个选项:

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

  • 只需在
    FRead()中注释swap调用
    code out。无论如何,您都是在使用它来加载文本文件,没有必要交换字符


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

  • 在“断开”之前检查较早的提交
  • 加载Mods\Aurora\Code\Aurora.sln
  • 删除不存在的.vcprojx项目
  • 再次添加所有3.vcproj文件,让它们转换为VS2015文件
  • 对于GameDll项目,添加预处理器定义
    \u静默\u索引\u散列\u弃用\u警告
  • <> LI>对于GAMEDLL项目,SET启用C++异常处理<代码> /EHSC
  • 注释掉上面的代码

请求重新打开问题。尽可能多地添加详细信息,并包括一个包含我正在处理的代码的GitHub存储库,因此可以重现该问题。您的证据表明该问题是由VS2012引入的,而不是C++11本身。@M.M证据表明是C++11导致的(作为VS2010和VS2012之间的主要变化),因为代码可以完美地编译为C++03而不是C++11(尽管可能是错误的)。如果需要进一步确认,代码就在那里。您可以尝试创建一个新的项目文件;升级旧项目文件有时会做一些奇怪的事情,
TypeInfo(char*)
等都是在CryCommon项目AutoTypeInfo.cpp中定义的。问题是GameDll编译得很好——它正确地找到了相关的.h文件,但是当它开始链接时,crycomon依赖项没有正确链接,这导致了错误。很难做出更多的猜测,因为您的项目处于一种奇怪的状态(.sln references.vcprojx,但只签入.vcproj文件;有像
#ifdef USE
..)这样的坏东西。请确保构建了CryCommon项目,并将其作为依赖项(添加为库)由GameDll引用。这正是正确的,谢谢!似乎VisualStudio没有完全正确地升级项目(通过安装VisualStudio2005到2015的所有版本并在每个版本中升级项目,无需编辑代码即可修复)。明天我将颁发赏金(必须等待21小时)。是的,正如M.M.上面所说的,当心VS p