How (if needed) to free dynamic memory when marshaling a CString from C ++ to C #?

I have a CString cs on the C ++ side and an IntPtr ip on the C # side that contains the cs value through a marshaling mechanism.

Then I just get the string I want as Marshal.PtrToStringAnsi (ip) and everything works fine, but I wonder if I should and if I should, how can I remove the unmanaged memory occupied by ip, i.e. cs?

+2


a source to share


2 answers


You can't, you don't know which allocator was used by the unmanaged code to instantiate the CString. Also, you will need to call the destructor of CString, you cannot get its address.



You're dead in water if that CString object is returned as a function return from a C ++ function that you call from C #. It is not clear from your question. You will have an uncontrolled memory leak. To fix this problem, you need a wrapper written in C ++ / CLI. Strings returned as function return values โ€‹โ€‹must be assigned to CoTaskMemAlloc () in order for the P / Invoke marshaler to clean up properly. C ++ code never does.

+1


a source


Unmanaged memory that was allocated by unmanaged code can only be freed by unmanaged code. Therefore, you need to add another unmanaged function that will take a pointer to the allocated string and free the memory. This function should then be called from managed code after the string is finished.

Example:



class Program
{
    [DllImport("test.dll")]
    static extern IntPtr GetString();

    [DllImport("test.dll")]
    static extern IntPtr FreeString(IntPtr ptr);

    static void Main()
    {
        IntPtr ptr = GetString();
        try
        {
            var str = Marshal.PtrToStringAnsi(ptr);
            // work with the string
        } 
        finally 
        {
            if (ptr != IntPtr.Zero)
            {
                FreeString(ptr);
            }
        }
    }
}

      

+1


a source







All Articles