你如何将'System :: String ^'转换为'TCHAR'?

时间:2011-04-14 17:14:06

标签: visual-studio-2010 visual-c++ casting c++-cli tchar

我问了一个涉及C ++和C#通信的问题here。问题得到解决,但又引发了一个新问题。

这将返回一个String(C#)

return Marshal.PtrToStringAnsi(decryptsn(InpData));

这需要一个TCHAR *(C ++)

lpAlpha2[0] = Company::Pins::Bank::Decryption::Decrypt::Decryption("123456");

我已经用谷歌搜索了如何解决这个问题,但我不确定为什么String上有胡萝卜(^)。是否最好将String的返回值更改为C ++可以接受的其他内容?或者我需要在分配值之前进行转换?

3 个答案:

答案 0 :(得分:4)

语法String^是C ++ / CLI talk for“(垃圾收集)对System.String的引用”。

String转换为C字符串有两种选择,这是表达TCHAR*的另一种方式。我在C ++中的首选方法是将转换后的字符串存储为C ++字符串类型,std::wstringstd::string,具体取决于您将项目构建为Unicode或MBCS项目。

在任何一种情况下,您都可以使用以下内容:

std::wstring tmp = msclr::interop::marshal_as<std::wstring>( /* Your .NET String */ );

std::string tmp = msclr::interop::marshal_as<std::string>(...);

一旦您将字符串转换为正确的宽或窄字符串格式,您就可以使用c_str()函数访问其C字符串表示,如下所示:

callCFunction(tmp.c_str());

假设callCFunction希望您传递C样式char*wchar_t*TCHAR*将“降级”为根据您的编译设置。

答案 1 :(得分:4)

字符串有^,因为它是托管引用的标记。基本上,它在非托管域中使用与*相同的方式,除了它只能指向对象类型,而不是指向其他指针类型,或者指向void。

基于_UNICODE预处理器定义,

TCHAR是#defined(或者可能是typedefed,我记不住了)charwchar_t。因此,我会使用它并编写代码两次。

内联:

TCHAR* str;
String^ managedString
#ifdef _UNICODE
str = (TCHAR*) Marshal::StringToHGlobalUni(managedString).ToPointer();
#else
str = (TCHAR*) Marshal::StringToHGlobalAnsi(managedString).ToPointer();
#endif

// use str.

Marshal::FreeHGlobal(IntPtr(str));

或作为一对转换方法,两者都假定输出缓冲区已经分配并且足够大。方法重载应该根据TCHAR的定义来选择正确的方法。

void ConvertManagedString(String^ managedString, char* outString)
{
    char* str;
    str = (char*) Marshal::StringToHGlobalAnsi(managedString).ToPointer();    
    strcpy(outString, str);    
    Marshal::FreeHGlobal(IntPtr(str));
}

void ConvertManagedString(String^ managedString, wchar_t* outString)
{
    wchar_t* str;
    str = (wchar_t*) Marshal::StringToHGlobalUni(managedString).ToPointer();    
    wcscpy(outString, str);    
    Marshal::FreeHGlobal(IntPtr(str));
}

答案 2 :(得分:2)

这是提出问题的一种非常漫无边际的方式,但如果你的意思是如何将String ^转换为char *,那么你使用之前使用的相同编组器,只是向后:

char* unmanagedstring = (char *) Marshal::StringToHGlobalAnsi(managedstring).ToPointer();

编辑:不要忘记在使用Marshal::FreeHGlobal时释放分配的内存。