开发者

c# interop marshalling and disposing

开发者 https://www.devze.com 2022-12-08 23:37 出处:网络
I have a DLL, which is designed in C++, included in a C# project and I have strange AccessViolationExceptions happening unrationally. I suspect that my garbage isn\'t collected correctly. I have an un

I have a DLL, which is designed in C++, included in a C# project and I have strange AccessViolationExceptions happening unrationally. I suspect that my garbage isn't collected correctly. I have an unmanaged method apiGetSettings (from the DLL) which should copy data to a Settings object (actually a struct in the original code, but .NET InterOp only allowed importing the data as class objects. I use the System.Runtime.InteropServices.Marshal methods to allocate and deallocate memory, but it might leave garbage behind that crashes everything.

Now, should I implement IDisposable methods in the Settings class (is it unmanaged?). If so, how do I dispose of the strings marshalled as UnmanagedType.ByValTStr and how do I disp开发者_运维问答ose of the 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);
}


No, you don't need to implement IDisposable. Your Settings class is a managed class (those attributes are just for runtime purposes) and will be garbage collected.

My first guess: you're allocating 43 bytes, but both your strings add up to over 70 bytes (remember, unless you're on ancient Win98/Me, the size of one character is 2 bytes), so you're not allocating enough. Use Marshal.SizeOf instead to dynamically detemine the size of the structure.

0

精彩评论

暂无评论...
验证码 换一张
取 消