从 C# 代码调用 delphi DLL 函数
Posted
技术标签:
【中文标题】从 C# 代码调用 delphi DLL 函数【英文标题】:Calling a delphi DLL function from C# Code 【发布时间】:2011-12-28 08:20:52 【问题描述】:我有一个在 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 方法,它抛出了一个异常: 调用 PInvoke 函数 'ProjTest!ProjTest.MyClass::InitModule' 使堆栈失衡。这可能是因为托管 PInvoke 签名与非托管目标签名不匹配。检查 PInvoke 签名的调用约定和参数是否与目标非托管签名匹配。
请帮帮我。我应该如何在 C# 中描述这些 DLL 函数?
【问题讨论】:
【参考方案1】:您不能从 C# 调用该 DLL。主要问题是两个of object
回调。 C# 中没有办法与之匹配。您将需要修改现有的 DLL 或添加中间适配器 DLL。就目前而言,您的 DLL 只能从 Delphi 或 C++ Builder 访问。
如果您可以修改 DLL,那么您需要进行的修改是删除 of object
。如果您需要回调对实例进行操作,那么您需要将实例作为参数传递。但是,C# 委托可以透明地包装所有内容,因此如果您需要从其他语言访问 DLL,您只需将实例作为参数传递,例如德尔福。
另一个问题是开放数组参数。这也不容易从其他语言访问。虽然有tricks,但我建议传递对第一个元素的引用而不是开放数组。开数组是 Delphi 独有的。
我也不明白你为什么使用byte
类型来保存数组长度。您应该为此使用Integer
。使用 byte 没有任何好处,您只需邀请溢出。另外,MainWindowHandle
在 Delphi 中不应该是 THandle
。应该是HWND
。
我对您的建议是修改 DLL 以具有与 C 兼容的接口,从而可以从支持该接口的所有语言访问。实际上,这将使所有主流编程语言都可以访问它。
【讨论】:
以上是关于从 C# 代码调用 delphi DLL 函数的主要内容,如果未能解决你的问题,请参考以下文章
从 Delphi“访问冲突”正确调用 DLL 中的 C++ 函数