简体   繁体   English

从C#Code调用delphi DLL函数

[英]Calling a delphi DLL function from C# Code

I have a DLL compiled in Delphi 2007 and an example using it in other Delphi project. 我有一个在Delphi 2007中编译的DLL和一个在其他Delphi项目中使用它的例子。 Here is a part of code: 这是代码的一部分:

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';

And here is my C# analog: 这是我的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);

The point is I've tried only InitModule method and it throwed an exception: A call to PInvoke function 'ProjTest!ProjTest.MyClass::InitModule' has unbalanced the stack. 关键是我只尝试过InitModule方法并抛出异常:调用PInvoke函数'ProjTest!ProjTest.MyClass :: InitModule'使堆栈失去平衡。 This is likely because the managed PInvoke signature does not match the unmanaged target signature. 这很可能是因为托管PInvoke签名与非托管目标签名不匹配。 Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature. 检查PInvoke签名的调用约定和参数是否与目标非托管签名匹配。

Please, help me with this. 请在这件事上给予我帮助。 How should I describe these DLL functions in C#? 我应该如何在C#中描述这些DLL函数?

You can't call that DLL from C#. 你不能从C#调用该DLL。 The main problem are the two of object callbacks. 主要问题是两个of object回调。 There's no way in C# to match that. 在C#中没有办法匹配它。 You will need to modify the existing DLL or add an intermediate adapter DLL. 您将需要修改现有DLL或添加中间适配器DLL。 As it stands your DLL is only accessible from Delphi or C++ Builder. 目前,您的DLL只能从Delphi或C ++ Builder访问。

If you can modify the DLL then the modification you need to make is to remove the of object . 如果您可以修改DLL,那么您需要进行的修改是删除of object If you need the callback to act on an instance then you will need to pass the instance as a parameter. 如果需要回调来对实例执行操作,则需要将实例作为参数传递。 However, C# delegates can wrap all that up transparently so you would only need to pass the instance as a parameter if you needed the DLL to be accessible from other languages, eg Delphi. 但是,C#委托可以透明地包装所有这些,因此如果您需要从其他语言(例如Delphi)访问DLL,您只需要将实例作为参数传递。

The other issue is the open array parameter. 另一个问题是open数组参数。 That is also not easily accessed from other languages. 这也不容易从其他语言访问。 Although there are tricks , I would recommend passing a reference to the first element rather than an open array. 虽然有技巧 ,但我建议将引用传递给第一个元素而不是开放数组。 Open arrays are unique to Delphi. 开放数组是Delphi独有的。

I also do not understand why you are using the byte type to hold array length. 我也不明白你为什么使用byte类型来保存数组长度。 You should use Integer for this. 你应该使用Integer There's nothing to gain from using byte and you simply invite overflow. 使用byte没有任何好处,你只需要邀请溢出。 Also, MainWindowHandle should not be THandle in Delphi. 另外, MainWindowHandle不应该是Delphi中的THandle It should be HWND . 它应该是HWND

My recommendation to you would be to modify the DLL to have a C compatible interface and thus be accessible from all languages that support that. 我对你的建议是修改DLL以具有C兼容接口,因此可以从支持它的所有语言访问。 In practice this would make it accessible from all mainstream programming languages. 在实践中,这将使其可以从所有主流编程语言访问。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM