不幸的是,我的任务是编译一个旧的C ++ DLL,以便它可以在Win 7 64位机器上运行。我没有C ++经验。我已经混淆了其他问题,但这个问题困扰了我,我没有在其他地方找到解决方案。以下代码抛出了C2440编译器错误。
错误:“错误C2440:'':无法转换为'std :: _ String_iterator< _Elem,_Traits,_Alloc>'到'LPCTSTR'“
代码:
#include "StdAfx.h"
#include "Antenna.h"
#include "MyTypes.h"
#include "objbase.h"
const TCHAR* CAntenna::GetMdbPath()
{
if(m_MdbPath.size() <= 0) return NULL;
return LPCTSTR(m_MdbPath.begin());
}
“m_MdbPath”在Antenna.h文件中定义为 string m_MdbPath;
任何人可以提供的帮助或指导都会非常有帮助。先感谢您。如果需要,我很乐意提供有关代码的其他详细信息。
答案 0 :(得分:2)
std :: string有一个.c_str()成员函数,可以完成你正在寻找的东西。它将返回一个const char *(const wchar_t * with std :: wstring)。 std :: string也有一个empty()成员函数,我建议使用nullptr而不是NULL宏。
const TCHAR* CAntenna::GetMdbPath()
{
if(m_MdbPath.empty()) return nullptr;
return m_MdbPath.c_str();
}
答案 1 :(得分:1)
解决方案:
const TCHAR* CAntenna::GetMdbPath()
{
if(m_MdbPath.size() <= 0) return NULL;
return m_MdbPath.c_str();
}
如果您可以保证您的程序使用MBCS
字符集选项(或者如果您使用的是Visual Studio,则字符集选项设置为Not Set
),将起作用,因为{ {1}}字符类型与std::string
类型相同。
但是,如果您的构建版本为TCHAR
,那么UNICODE
字符类型将与std::string
类型不同,因为TCHAR
被定义为宽字符,而不是单字节字符。因此,返回TCHAR
将产生编译器错误。因此,您的原始代码以及返回c_str()
的暂定修复可能会起作用,但就使用的类型而言,它在技术上是错误的。
您应该直接使用提供给您的函数的类型 - 如果类型为std::string::c_str()
,那么您应该使用基于TCHAR
的类型,但同样,TCHAR
是一种根据构建类型更改定义的类型。
事实上,如果代码是TCHAR
构建并且修复编译器错误,代码将在运行时失败,你转换为UNICODE
以保持编译器安静。您不能将字符串指针类型转换为另一个字符串指针类型。转换不是转换,只是转换不会将窄字符串转换为宽字符串,反之亦然。你最终会使用或显示奇怪的字符,更糟糕的是,一个程序随机奇怪的行为和崩溃。
除此之外,您永远不知道何时需要构建DLL的UNICODE版本,因为MBCS构建变得越来越少见。通过原始帖子,DLL的LPCTSTR
用法表明是的,这个DLL可能(甚至已经)为UNICODE构建。
您可以使用一些替代解决方案。请注意,其中一些解决方案可能要求您在字符串类型之外进行其他编码更改。如果您正在使用C ++流对象,则可能还需要更改它们以匹配字符类型(例如,TCHAR
和std::ostream
)
解决方案1.使用std::wostream
,其中要使用的字符串类型取决于构建类型。
例如:
typedef
然后使用#ifdef UNICODE
typedef std::wstring tchar_string;
#else
typedef std::string tchar_string;
#endif
代替tchar_string
。在MBCS和UNICODE构建之间切换将无需强制转换strin类型,但需要编码更改。
解决方案2.使用std::string
将typedef
用作TCHAR
模板中的基础字符类型。
例如:
std::basic_string
在您的应用中使用typedef std::basic_string<TCHAR> tchar_string;
。您获得与tchar_string
相同的公共接口,这允许您无缝切换MBCS和UNICODE构建(关于字符串类型)。
解决方案3.使用UNICODE构建并完全删除MBCS构建
如果您正在构建的应用程序是新应用程序,则在创建新应用程序时,std::(w)string
是默认选项(至少在Visual Studio中)。那么你真正需要做的就是使用UNICODE
。
这与确保使用std::wstring
的原始解决方案相反,但IMO这个解决方案更有意义,如果只有一个构建类型。 MBCS构建变得越来越少,并且基本上应该仅用于遗留应用程序。