【发布时间】:2020-01-11 19:44:40
【问题描述】:
我正在将我的软件与旧硬件集成,可用于集成的 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 中。 有人可以帮我吗?
【问题讨论】:
-
这个 DLL 的设计者犯了一个大错误,使用了
TObject,或者任何类型的对象。它不兼容互操作。它必须是完全相同版本的 Delphi / 编译器才能工作,即使那样它仍然是错误的。相反,它应该具有互操作安全的东西,例如接口。
标签: c# delphi dllimport stdcall