I usually use a template to make the P / invoke declaration private and use IntPtrstructs instead. Provide a publicly accessible marshalling method. (You can also get rid of unsafe ones this way.)
[DllImport(DLLPath, CallingConvention = CallingConvention.Cdecl)]
private extern static int AMRecoveryModeDeviceReboot(IntPtr device, byte[] paramByte, int u1, int u2, int u3)
public static int AMRecoveryModeDevice(ref AMRecoveryDevice device, byte[] paramByte, int u1, int u2, int u3) {
var ptr = Marshal.AllocHGlobal(Marshal.SizeOf(device));
Marshal.StructureToPointer(device, ptr, false);
int result = AMRecoveryModeDeviceReboot(ptr, paramByte, u1, u2, u3);
device = (AMRecoveryDevice)Marshal.PtrToStructure(ptr, typeof(AMRecoveryDevice));
Marshal.FreeHGlobal(ptr);
return result;
}
For the AMRecoveryDevice structure, you must also use IntPtr for the callback delegate.
[MarshalAs(UnmanagedType.FunctionPtr)]
private IntPtr _callback;
public DeviceRestoreNotificationCallback callback {
get { return (DeviceRestoreNotificationCallback)Marsal.GetDelagateFromFunctionPointer(_callback, typeof(DeviceRestoreNotificationCallback)); }
set { _calback = Marshal.GetFunctionPointerFromDelegate(value); }
}
source
share