PInvoke: When is the memory allocated by the CLR marshaller freed?

130 views Asked by At

PInvoke was used to pass the following structure from VB.net to unmanaged C when the app starts up. All the values are passed in correctly as I step through the code. Inside the called C method I save a the ptr to the passed in struct.

<StructLayout(LayoutKind.Sequential)>
Structure teststruct
    <MarshalAs(UnmanagedType.I2)> Public TestData As Short
    <MarshalAs(UnmanagedType.I2)> Public TestData2 As Short
    <MarshalAs(UnmanagedType.I2)> Public TestData3 As Short
    <MarshalAs(UnmanagedType.ByValArray, ArraySubType:=UnmanagedType.I2, SizeConst:=256)> Public TestData4() As Short
End Structure

//Matching C struct
struct teststruct
{
    short TestData;
    short TestData2;
    short TestData3;
    short TestData4[256];
};

//The method in C that saves ptr to the struct that is passed in (Worked with VB6)
struct teststruct *VCstruct;

void DllCallbackFunc(struct teststruct *VBStruct)
{

    VCstruct = VBStruct;

}

After I save the ptr to the passed in struct, the ptr be invalid as soon as the function returns to VB.net.

I suspect that the marshaller allocated memory is freed after the callback function returns

Is there a way to tell the marshaller to NOT deallocate the memory it allocated during marshaling?

Appreciate any comments. Thanks

1

There are 1 answers

0
David Heffernan On

The pointer that the p/invoke marshaler passes to the unmanaged code is valid only until the unmanaged function returns. You have two options, as I see it:

  1. Have the calling code pass a pointer that remains valid for as long as the unmanaged code retains a copy of the pointer. That will require a signature change to pass an IntPtr. And calls to Marshal.AllocHGlobal and Marshal.StructureToPtr.
  2. Have the unmanaged code take a copy of the structure rather than a copy of the address of the structure.

The latter option is more commonly chosen.