在 C# 中使用 DLLImport 的 Delphi 对象类型存在问题



我正在将我的软件与传统硬件集成,可用于集成的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.

看看我的代码,我认为问题出在德尔福的文章中。 有人可以帮助我吗?

不幸的是,我完全同意Jerry Dodge的观点,该库的接口以错误的方式实现。因此,您需要在Delphi中编写一个代理库,该库将具有适合您需求的接口。首先,您需要确定用于dll的Delphi版本。"PEiD"(可移植可执行iDentifier(将帮助您使用旧版本的Delphi,而"Exeinfo PE"则可以帮助您使用较新版本的Delphi。代理应以相同或非常接近的版本编写。代理的接口可以是一堆简单的函数,也可以是成熟的进程外COM,这取决于您。您甚至可以编写单独的 EXE,它将通过 JSON 将数据发送到您的应用。并且不要忘记,Delphi对象可以手动或引用计数(如Apple的ARC(内存管理,具体取决于开发人员的需求。

最新更新