Я интегрирую свое программное обеспечение с устаревшим оборудованием, и документация DLL, доступная для интеграции, была сделана в Delphi.
В ее документации говорится, что вызов должен быть сделан следующим образом:
Function ConfigurarOnLine( Sender: TObject; Com: Byte; Velocidade: Word;
EvTrata: TNotifyOnLine; EvGrava: TNotify;
EvError: TNotifyError; EvRegOff: TNotifyRegOff): Boolean; stdcall; external 'HenryOn.Dll' Index 1;
TNotifyOnLine = Procedure (Numero: PChar; Tipo, Funcao, Relogio: Byte) of Object;
TNotifyError = Procedure (Erro, Versao : Byte) of Object;
TNotify = Procedure of Object;
TNotifyRegOff = Procedure (RelNum: Byte);
В ходе некоторых исследований мне удалось получить следующий код:
public struct Method
{
public IntPtr code;
public IntPtr data;
}
public delegate void TNotifyOnLine([MarshalAs(UnmanagedType.LPStr)]string Numero, byte Tipo, byte Funcao, byte Relogio);
public delegate void TNotifyError(byte Erro, byte Versao);
public delegate void TNotify();
public delegate void TNotifyRegOff(byte RelNum);
[DllImport("HenryOn.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi, EntryPoint = "ConfigurarOnLine")]
public static extern bool ConfigurarOnLine(object Sender,
byte Com,
int Velocidade,
Method EvTrata,
Method EvGrava,
Method EvError,
Method EvRegOff);
private void btnIniciar_Click(object sender, EventArgs e)
{
HenryOn.TNotifyOnLine evTrata = EvTrata;
IntPtr pEvTrata = Marshal.GetFunctionPointerForDelegate(evTrata);
HenryOn.Method mpEvTrata;
mpEvTrata.code = pEvTrata;
mpEvTrata.data = IntPtr.Zero;
HenryOn.TNotify evGrava = EvGrava;
IntPtr pEvGrava = Marshal.GetFunctionPointerForDelegate(evGrava);
HenryOn.Method mpEvGrava;
mpEvGrava.code = pEvGrava;
mpEvGrava.data = IntPtr.Zero;
HenryOn.TNotifyError evError = EvError;
IntPtr pEvError = Marshal.GetFunctionPointerForDelegate(evError);
HenryOn.Method mpEvError;
mpEvError.code = pEvError;
mpEvError.data = IntPtr.Zero;
HenryOn.TNotifyRegOff evRegOff = EvRegOff;
IntPtr pEvRegOff = Marshal.GetFunctionPointerForDelegate(evRegOff);
HenryOn.Method mpEvRegOff;
mpEvRegOff.code = pEvRegOff;
mpEvRegOff.data = IntPtr.Zero;
var retorno = HenryOn.ConfigurarOnLine(null,
1,
9600,
mpEvError,
mpEvError,
mpEvError,
mpEvError);
}
Но при выполнении возникает ошибка:
System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
См. Мой код, я думаю, проблема в Delphi TObject. Кто-нибудь может мне помочь?