How to marshal to ANSI string via attribute?
As stated in the linked article, when using [return: MarshalAs(UnmanagedType.LPStr)]
, the memory of the native string is freed by the CLR using FreeCoTaskMem()
. If you manually create the managed string object via Marshal.PtrToStringAnsi()
, the memory is not freed at all.
If it crashes, then probably the string was not created on the unmanaged side via CoTaskMemAlloc()
, but via new() or malloc() (for example). The API of SDL_GetError()
should state whose job it is to free the native string and how.
I did some digging. The source for SDL_GetError
is:
const char *
SDL_GetError(void)
{
static char errmsg[SDL_ERRBUFIZE];
return SDL_GetErrorMsg(errmsg, SDL_ERRBUFIZE);
}
We can see that the memory for the string is allocated as a static char array. It is overwritten every time SDL_GetError
is called. As such we can't and don't need to free it.
Since the [return: MarshalAs.*]
methods all attempt to free memory after marshalling the type, they will not work (and further cause the program to crash).
As such, your (my) original solution is optimal.