Difference between MarshalAs(UnmanagedType.LPWStr) and Marshal.PtrToStringUni()
.net, c#, dllimport, extern, marshalling
Solution
Writing the PInvoke signature for a method which returns a `char* / wchar_t*` requires a lot of care because the CLR special cases `string` return types. It makes the following assumptions
- The memory for the `char*` must be freed after converting to `string`
- The memory was allocated with `CoTaskMemAlloc`
If either of these aren't true (usually the case) then the program will run into errors.
In general it's best to simply return an `IntPtr` and manually marshal the string as you've done with `PtrToStringUni`.
Problem
I would like to import a function like this: ``` [return: MarshalAs(UnmanagedType.LPWStr)] [DllImport("DLL.dll", EntryPoint="FuncUtf16", ExactSpelling=true, PreserveSig=true, CharSet=CharSet.Unicode)] public static extern string Func(); ``` But this gives me an error like this: "Windows has triggered a breakpoint in Test.exe. This may be due to a corruption of the heap, which indicates a bug in Test.exe or any of the DLLs it has loaded. " And when I press "Continue" repeatedly, the function does give the expected output. However, when I chance the above declaration to: ``` [DllImport("DLL.dll", EntryPoint="FuncUtf16", ExactSpelling=true, PreserveSig=true, CharSet=CharSet.Unicode)] public static extern IntPtr Func(); ``` (changing the return type to IntPtr) and call it as follows: ``` Dim a As IntPtr = Func() Dim Str As String = Runtime.InteropServices.Marshal.PtrToStringUni(a) ``` , I get no errors and it works perfectly fine! Whats wrong with using the "MarshalAs" way of declaring a function in a dll?