Consider your original p / invoke:
[DllImport(...)] public static extern string GetClassName();
Processing the return value by the marshaller is the key. This is sorted as a string C, i.e. a pointer to an array of characters with a null character. Since the data comes from native to managed and is not allocated in managed code, the structure assumes that it is not responsible for releasing it. Native code cannot free it because it is no longer running.
So the policy is that the p / invoke marshaller assumes that the character array has been allocated on the common COM heap. And so it calls CoTaskMemFree
. I am sure that the array was not allocated on the common COM heap. Thus, your code has always been broken. In older versions of .net, the CoTaskMemFree
call failed. In recent versions, error with error. I’m not sure if the change is in the .net infrastructure or the underlying platform, but that doesn’t mean much since the source code is everywhere broken.
Automatic line sorting is supported in exactly the same way in .net 4.5 as in previous versions. But you have to do it right. If you want to use the return value of string
with default marshalling, allocate an array of characters in the COM heap with a call to CoTaskMemAlloc
.
If the returned string is actually statically distributed and does not need to be freed, you have two obvious options:
- In managed code, switch to using
IntPtr
and PtrToStringAnsi
. This is simple enough for you because you move the PtrToStringAnsi
call inside your _GetClassName
wrapper and present the same open interface as before. - In the native code, continue and call
CoTaskMemAlloc
, and then copy the static buffer to this buffer allocated by the buffer.
source share