从C#代码调用delphi DLL函数
我在Delphi2007中编译了一个DLL,并在其他Delphi项目中使用了一个示例。以下是代码的一部分:从C#代码调用delphi DLL函数,c#,delphi,pinvoke,C#,Delphi,Pinvoke,我在Delphi2007中编译了一个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:TErro
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#模拟:
关键是我只尝试了InitModule方法,它抛出了一个异常:
调用PInvoke函数“ProjTest!”!ProjTest.MyClass::InitModule'已使堆栈不平衡。这可能是因为托管PInvoke签名与非托管目标签名不匹配。检查PInvoke签名的调用约定和参数是否与目标非托管签名匹配
请帮我做这个。我应该如何在C#中描述这些DLL函数?您不能从C#调用该DLL。主要问题是对象的两个
回调。在C#中没有办法与之匹配。您需要修改现有DLL或添加中间适配器DLL。正如你所说的,你的DLL只能从Delphi或C++ Builder访问。p>
如果可以修改DLL,则需要进行的修改是删除对象的。如果需要回调对实例执行操作,则需要将实例作为参数传递。但是,C#委托可以透明地包装所有这些内容,因此,如果需要从其他语言(如Delphi)访问DLL,则只需将实例作为参数传递
另一个问题是开放数组参数。这也不容易从其他语言访问。尽管有,我还是建议传递对第一个元素的引用,而不是一个开放数组。开放数组是Delphi独有的
我也不明白为什么要使用字节
类型来保存数组长度。您应该使用Integer
进行此操作。使用字节并没有什么好处,只会导致溢出。另外,在Delphi中,MainWindowHandle
不应该是THandle
。它应该是HWND
我建议您修改DLL,使其具有与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);