How do you convert a 'System::String ^' to 'TCHAR'?

岁酱吖の 提交于 2020-01-11 10:25:32

问题


i asked a question here involving C++ and C# communicating. The problem got solved but led to a new problem.

this returns a String (C#)

return Marshal.PtrToStringAnsi(decryptsn(InpData));

this expects a TCHAR* (C++)

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

i've googled how to solve this problem, but i am not sure why the String has a carrot(^) on it. Would it be best to change the return from String to something else that C++ would accept? or would i need to do a convert before assigning the value?


回答1:


That is a really rambling way to ask the question, but if you mean how to convert a String ^ to a char *, then you use the same marshaller you used before, only backwards:

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

Edit: don't forget to release the memory allocated when you're done using Marshal::FreeHGlobal.




回答2:


String has a ^ because that's the marker for a managed reference. Basically, it's used the same way as * in unmanaged land, except it can only point to an object type, not to other pointer types, or to void.

TCHAR is #defined (or perhaps typedefed, I can't remember) to either char or wchar_t, based on the _UNICODE preprocessor definition. Therefore, I would use that and write the code twice.

Either inline:

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));

or as a pair of conversion methods, both of which assume that the output buffer has already been allocated and is large enough. Method overloading should make it pick the correct one, based on what TCHAR is defined as.

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));
}



回答3:


The syntax String^ is C++/CLI talk for "(garbage collected) reference to a System.String".

You have a couple of options for the conversion of a String into a C string, which is another way to express the TCHAR*. My preferred way in C++ would be to store the converted string into a C++ string type, either std::wstring or std::string, depending on you building the project as a Unicode or MBCS project.

In either case you can use something like this:

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

or

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

Once you've converted the string into the correct wide or narrow string format, you can then access its C string representation using the c_str() function, like so:

callCFunction(tmp.c_str());

Assuming that callCFunction expects you to pass it a C-style char* or wchar_t* (which TCHAR* will "degrade" to depending on your compilation settings.



来源:https://stackoverflow.com/questions/5666997/how-do-you-convert-a-systemstring-to-tchar

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!