Reputation: 9825
Suppose I have the following C++ function that is exported in a library:
void foo(const wchar_t* text);
and C# code that uses that function:
[DllImport("bla.dll")]
static extern void foo([MarshalAs(UnmanagedType.LPWStr)] string text);
void Bar()
{
string s = "hello";
foo(s);
}
foo
or does the pointer point to the buffer of s
?foo
)?What's the behavior if text
is marshalled as:
UnmanagedType.LPWStr
UnmanagedType.BStr
Upvotes: 2
Views: 505
Reputation: 42225
- Does the .net marshaller copy the string when I call foo or does the pointer point to the buffer of s?
The specific case of an LPWSTR being passed by value means that the managed string gets pinned and used directly by native code, see here. In all other cases, the string is copied, see here.
- If the value is copied, when is it cleaned up?
The marshaller does any freeing after the function call returns.
What's the behavior if text is marshalled as:
UnmanagedType.LPWStr
UnmanagedType.BStr
The ultimate behaviour is the same, in that the pointer passed to the native function is not valid after the function call returns. In the case of LPWStr it will point to the same memory as used by the managed string (which may move after the native function returns), for a BStr, it will point to a temporary buffer allocated by the marshaller (which will be freed after the native function returns).
If you need the native function to take ownership of the pointer, you'll need to pass in an IntPtr
which points to some memory which you allocated yourself in a suitable way (perhaps by calling into some native code, perhaps by using AllocHGlobal
, etc). The pointer will need to be manually freed by you or the native code using the same mechanism.
Upvotes: 2