从C#代码调用delphi DLL函数

我有一个在Delphi 2007中编译的DLL和一个在其他Delphi项目中使用它的例子。 这是代码的一部分:

TErrorCallback = function(Msg:PChar):byte of object; TSaveEventCallback = function (Line:PChar; HiCode:PChar; LoCode:PChar; MobileNo:PChar):byte of object; function InitModule(ErrorCallback:TErrorCallback; SaveEventCallback :TSaveEventCallback; MainWindowHandle:THandle; Sock_Event:integer):byte; stdcall; external 'My.dll' name 'InitModule'; function DLLSocketEvent(var msg: TMessage): byte; stdcall; external 'My.dll' name 'DLLSocketEvent'; function InitObjList(Objs: array of PChar; NumObjs: byte; Name: PChar):byte; stdcall; external 'My.dll' name 'InitObjList'; 

这是我的C#模拟:

 class Message { unsigned int msg; int wParam; int lParam; int result; }; delegate byte ErrorCallbackDelegate(string msg); delegate byte SaveEventCallbackDelegate(string line, string hiCode, string loCode, string mobileNo); [DllImport("My.dll")] static extern byte InitModule(ErrorCallbackDelegate errorCallback, SaveEventCallbackDelegate saveEventCallback, IntPtr mainWindowsHandle, Int32 sockEvent); [DllImport("My.dll")] static extern byte DllSocketEvent(Message msg); [DllImport("My.dll")] static extern byte InitObjList(string[] objs, byte numObjs, string name); 

关键是我只尝试过InitModule方法并抛出exception:调用PInvoke函数’ProjTest!ProjTest.MyClass :: InitModule’使堆栈失衡。 这很可能是因为托管的PInvoke签名与非托管目标签名不匹配。 检查PInvoke签名的调用约定和参数是否与目标非托管签名匹配。

请在这件事上给予我帮助。 我应该如何在C#中描述这些DLL函数?

你不能从C#调用该DLL。 主要问题是两个of object回调。 在C#中没有办法匹配它。 您将需要修改现有的DLL或添加中间适配器DLL。 目前,您的DLL只能从Delphi或C ++ Builder访问。

如果您可以修改DLL,那么您需要进行的修改是删除of object 。 如果需要回调来对实例执行操作,则需要将实例作为参数传递。 但是,C#委托可以透明地包装所有这些,因此如果您需要从其他语言(例如Delphi)访问DLL,您只需要将实例作为参数传递。

另一个问题是open数组参数。 这也不容易从其他语言访问。 虽然有一些技巧 ,但我建议将引用传递给第一个元素而不是一个开放数组。 开放数组是Delphi独有的。

我也不明白你为什么使用byte类型来保存数组长度。 你应该使用Integer 。 使用byte没有任何好处,你只需要邀请溢出。 另外, MainWindowHandle不应该是Delphi中的THandle 。 它应该是HWND

我对你的建议是修改DLL以具有C兼容接口,因此可以从支持它的所有语言访问。 在实践中,这将使其可以从所有主流编程语言访问。