Delphi DLL function call from C # code

I have a DLL compiled in Delphi 2007 and an example using it in another Delphi project. Here is the piece 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 # counterpart:

 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 bottom line is that I tried only the InitModule method and threw an exception: The PInvoke function call "ProjTest! ProjTest.MyClass :: InitModule" has an unbalanced stack. This is likely due to the fact that the PInvoke managed signature does not match the unmanaged target signature. Verify that the calling agreement and PInvoke signature settings match the target unmanaged signature.

Please help me with this. How to describe these DLL functions in C #?

+7
source share
1 answer

You cannot call this DLL from C #. The main problem is two of object callbacks. In C # there is no way to match this. You will need to modify the existing DLL or add an intermediate DLL adapter. At its core, your DLL is only available from Delphi or C ++ Builder.

If you can change the DLL, then you will need to change it to remove of object . If you need a callback to work with an instance, you need to pass the instance as a parameter. However, C # delegates can wrap all this in a transparent way, so you will only need to pass the instance as a parameter if you need a DLL for access from other languages, for example. Delphi

Another problem is the open array parameter. It is also not easy to get from other languages. Although there are tricks , I would recommend passing the reference to the first element, not the open array. Open arrays are unique to Delphi.

I also don't understand why you are using the byte type to store the length of an array. You must use Integer for this. There is nothing to gain from using a byte, and you just invite overflow. In addition, MainWindowHandle should not be THandle in Delphi. It must be HWND .

My recommendation would be to modify the DLL to have a C-compatible interface and therefore be accessible from all languages ​​that support this. In practice, this will make it accessible from all major programming languages.

+11
source

All Articles