C # interop marshalling and disposing

I have a DLL that is developed in C ++, included in a C # project, and I have strange AccessViolationExceptions happening irrationally. I suspect that my garbage is not collected correctly. I have an unmanaged apiGetSettings method (from the DLL) that should copy data to the Settings object (this is actually a structure in the source code, but .NET InterOp allowed me to import data as objects of the class. I use System.Runtime.InteropServices. Marshal methods allocating and freeing memory, but it can leave garbage that crashing everything.

Now, should I implement the IDisposable methods in the Settings class (unmanaged?). If so, how can I get rid of strings ordered as UnmanagedType.ByValTStr, and how can I get rid of settings objects?

using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
class Settings
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 33)]
internal string d;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]
internal string t;
internal int b;
}

[DllImport(".\\foobar.dll", EntryPoint = "getSettings")]
private static extern int apiGetSettings(IntPtr pointerToSettings);

void GetSettings(ref Settings settings)
{
int debug = 0;

// Initialize a pointer for the structure and allocate memory
IntPtr pointerToSettings = Marshal.AllocHGlobal(43);

// Connect the pointer to the structure
Marshal.StructureToPtr(settings, pointerToSettings, true);

// Point the pointer
debug = apiGetSettings(pointerToSettings);

// Copy the pointed data to the structure
Marshal.PtrToStructure(pointerToSettings, settings);

// Free the allocated memory
Marshal.FreeHGlobal(pointerToSettings);
}
+3
source share
1 answer

No, you do not need to implement IDisposable. The Settings class is a managed class (these attributes are for execution purposes only) and garbage will be collected.

My first assumption: you allocate 43 bytes, but both of your lines are more than 70 bytes (remember that if you are not on the ancient Win98 / Me, the size of one character is 2 bytes) it is not enough to distribute. Instead, use Marshal.SizeOf to dynamically determine the size of the structure.

+1
source

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


All Articles