Will the memory be used by MarshalAs (UnmanagedType.LPWStr)?

I am trying to write pinvoke for the ITaskTrigger :: GetTriggerString method (defined in http://msdn.microsoft.com/en-us/library/windows/desktop/aa381866(v=vs.85).aspx ). If you look at the page, it says that the calling method is responsible for freeing up (via CoTaskMemFree) LPWSTR, which the first argument refers to. Although I could do it manually in .NET, or I could write my own marshaler using ICustomMarshaler, I was wondering if using the MarshalAs attribute (UnmanagedType.LPWStr) for this particular argument would free memory accordingly.

Can someone give an idea?

+6
source share
1 answer

First of all: you are talking about COM Interop here ( ITaskTrigger is a COM interface), not P / Invoke. There are different interaction rules for the two, so it is important to keep them straightforward. For example, you will need to define C # interaction wrappers for the entire interface, and not just the method you want. They should start: pinvoke.net

Short answer: you are lucky because the CLR should take care of things right for you.

The longer answer includes various types of sorting of the COM interaction code, depending on the types of parameters, directions, and which attributes you add to your interop subscriptions.

In this case, the type of parameter that you get when you call is the " out string " parameter with the MarshalAs(UnmanagedType.LPWSTR) attribute MarshalAs(UnmanagedType.LPWSTR) . When the COM server provides a call with the "out" parameter for the LPWSTR line LPWSTR , assuming the server continues to end the transaction, it allocates a memory buffer using CoTaskMemAlloc() and returns it to you. (If it was a different type of string, for example, BSTR , the specific memory allocation call may be different, but the basic concept is the same.) At this point, you are responsible for clearing this memory when you no longer need it using the appropriate CoTaskMemFree() call.

This is a special type of operation called a “link to link”: the parameter you are sending is already a link parameter, but the COM server will replace it with another link. For a good explanation of this process, see the “Memory Ownership” section of this MSDN journal article . As you can see from this article, when the CLR receives data back from the "out" parameter in the reference type, it recognizes that it is responsible for freeing this memory. While marshaling that accesses managed code, it uses the MarshalAs attribute to determine that it is a pointer to a string type LPWSTR in COM, and therefore it must be allocated using CoTaskMemAlloc() . After creating a managed row from the data, it will call CoTaskMemFree() in the source buffer on your behalf. The data you receive will be fully managed and you won’t have to solve any ownership problems.

+6
source

Source: https://habr.com/ru/post/901918/


All Articles