I wrote a managed C++ class that has the following function:
void EndPointsMappingWrapper::GetLastError(char* strErrorMessage)
{
strErrorMessage = (char*) Marshal::StringToHGlobalAnsi(_managedObject->GetLastError()).ToPointer();
}
As you can see, this is a simple method to copy the managed string of the last error to the unmanaged world (char*).
From my unmanaged class I call the method like this:
char err[1000];
ofer->GetLastError(err);
Putting a breakpoint at the managed C++ method shows that the string is successfully translated into the char*. However, once I return to the unmanaged class, the content of err[1000] is lost and it's empty again.
You are assigning the value of the passed parameter (strErrorMessage) instead of copying to that address the content of the buffer returned by Marshal::StringToHGlobalAnsi.
A correct implementation should be:
void EndPointsMappingWrapper::GetLastError(char* strErrorMessage, int len)
{ char *str = (char*) Marshal::StringToHGlobalAnsi(_managedObject->GetLastError()).ToPointer();
strncpy(strErrorMessage,str,len);
strErrorMessage[len-1] = '\0';
Marshal::FreeHGlobal(IntPtr(str));
}
The length is the size of the buffer passed.
strncpy() will copy at the most len bytes. If there is no null byte among the first n bytes of the str, the destination string won't be null terminated. For that reason we force the '\0' in the last byte of the buffer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With