2

我在这里问了一个涉及 C++ 和 C# 通信的问题。问题解决了,但又引出了一个新问题。

这将返回一个字符串(C#)

return Marshal.PtrToStringAnsi(decryptsn(InpData));

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

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

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

4

3 回答 3

5

字符串有一个^,因为这是托管引用的标记。基本上,它的使用方式与*非托管区相同,只是它只能指向对象类型,不能指向其他指针类型或 void。

TCHAR是 #defined (或者可能是 typedefed,我不记得了)到charor wchar_t,基于 _UNICODE 预处理器定义。因此,我会使用它并编写两次代码。

内联:

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));
}
于 2011-04-14T17:37:18.037 回答
4

语法String^是 C++/CLI talk for "(garbage collected) reference to a System.String"。

您有几个选项可以将 aString转换为 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*将“降级”到取决于您的编译设置。

于 2011-04-14T17:24:14.667 回答
2

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

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

编辑:不要忘记释放使用完后分配的内存Marshal::FreeHGlobal

于 2011-04-14T17:21:26.527 回答