Using System::String::Format with LPTSTR (wchar_t *) stings from unmanaged code

StackOverflow https://stackoverflow.com/questions/22854899

  •  27-06-2023
  •  | 
  •  

質問

I have a LPTSTR (wchar_t *) string that gets returned from FormatMessage that I'd like to use in a String::Format but I can't figure out how to specify it. Consider these code lines:

wchar_t * szErrMsg = L"Error Msg from Unmanaged";  // faking the message from FormatMessage
System::String^ AString = gcnew System::String(szErrMsg); // works
System::String^ BString = System::String::Format(L"{0}.", AString); // works
System::String^ CString = System::String::Format(L"{0}.", szErrMsg); // no overloads match
System::String^ DString = System::String::Format(L"{0}.", L"Error Msg from Unmanaged"); // works

AString and BString work fine. Interestingly enough DString does also. But not CString.

I can certainly change all of the pieces of the message into ::String objects (like AString) and then format the entire message into another String (like BString) but I'd rather forgo that if it's possible to just correctly specify CString so that it will work. I suspect it's possible because DString works.

I also tried ::StringBuilder and got some intersting results with .Append - apparently the compilier thought the szErrMsg was a bool for some reason. It even gave me the performance warning about bool conversion.

The final message has about three parts and it would be nice if I could use the one call to ::Format to build it.

Suggestions?

役に立ちましたか?

解決

The 2nd argument of String::Format() is a param array. Roughly similar to ... as used in the C language for functions like printf(). Under the hood, it is a managed array of objects, the declaration looks like this in C++/CLI syntax:

   static String^ Format(String^ format, ... array<Object^>^ args);

So a hard requirement is that the arguments you pass are convertible to System::Object. The Format() method relies on these objects implementing ToString(), all managed objects do.

No problem with AString of course, it is a managed string and its ToString() method simply returns the same string.

No problem with the string literal, the compiler implicitly converts any string literal to System::String. It automatically emits the code necessary to create the String object. Note that prefixing the literal with L isn't necessary.

Big problem with wchar_t*, it is an unmanaged pointer. They are never implicitly convertible to any managed type. System::IntPtr would be the closest possible match but it is not useful at all since this is just an untyped pointer value. So you have to write the code yourself to make the conversion. You already know what it looks like:

   String^ CString = String::Format("{0}.", gcnew String(szErrMsg)); 
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top