类 StrTrait 中的差异阻止了符号解析?

Symbol resolution prevented by differences in class StrTrait?

提问人:rtischer8277 提问时间:3/2/2016 最后编辑:πάντα ῥεῖrtischer8277 更新时间:3/2/2016 访问量:221

问:

在新的应用程序 MyProg.exe 中,我想重用在另一个 dll/lib MyDll.lib/.dll 中定义的函数。调用具有以下签名:

CString CallToDllCodeFuncFromExe( const CString & someStr );

在 MyProg 中.exe我 #include dll 的头文件并输入 MyDll.lib,以便链接器可以解析它,但我得到一个未解析的符号。

MSDN 告诉我,发生这种情况的一个原因可能是“使用了函数,但参数的类型或数量与函数定义不匹配”。这里似乎就是这种情况。以下是从 exe 错误消息和 MyDll.lib 的转储站中获取的函数的未破坏签名的比较。请注意,StrTraitMFC 和 StrTraitMFC_DLL 之间存在差异,这使它无法解析:

MyProg.exe 的生成错误消息(未解析的符号):

__cdecl CallToDllCodeFuncFromExe(class ATL::CStringT< wchar_t,class StrTraitMFC< wchar_t,class ATL::ChTraitsCRT< wchar_t> > > const &)

CallToDllCodeFuncFromExe 的 MyDll.lib 的 Dumpbin /exports:

__cdecl CallToDllCodeFuncFromExe(类 ATL::CStringT< wchar_t,类 StrTraitMFC_DLL< wchar_t,类 ATL::ChTraitsCRT< wchar_t> > > 常量 &))

但在实践中,我注意到有一种解决方法。我需要做的就是对函数进行模板化,调用工作正常。下面是 IntToStr,其中包含一个按值划分的令牌模板参数:

template< int N > CString IntToStr( int N )
{
  CString intToStr;
  intToStr.Format( L"%d", N );
  return intToStr;
}

电话是:

CString str = IntToStr< 33 >( 33 );

导出的函数如下所示:

类 ATL::CStringT< wchar_t,类 StrTraitMFC_DLL< wchar_t,类 ATL::ChTraitsCRT< wchar_t> > > __cdecl IntToString(int)

我的问题是,为什么这种解决方法有效,为什么非模板化调用不起作用?它只是Visual Studio不一致/错误,还是这里有更多的C++抽象?

C++ MFC exe atl 未解析的外部

评论

3赞 Igor Tandetnik 3/3/2016
CString是一个 typedef,它根据项目设置解析为不同的类型。作为推论,如果在 DLL 的公共接口中使用(出于多种原因,这是不明智的),则它只能由使用完全相同的设置生成的客户端使用;所有模块必须就确切的含义达成一致。在您的例子中,区别在于(一个将其作为静态库,另一个作为 DLL)。CStringCStringProject > Properties > General > Use of MFC
2赞 Igor Tandetnik 3/3/2016
至于模板函数 - 它根本不是从 DLL 导入的。您已在标头中提供了实现 - 此实现在调用站点内联。EXE 实际上并不依赖于 DLL(在没有的情况下运行它,请自行查看)。
0赞 IInspectable 3/3/2016
@IgorTandetnik:这应该是一个答案,而不仅仅是一个评论。
0赞 rtischer8277 3/3/2016
“至于模板函数 - 它根本不是从DLL导入的。您已在标头”
1赞 Igor Tandetnik 3/3/2016
用关键字标记您的非模板,这样您就不会出现重新定义错误。inline

答: 暂无答案