How to call this function in delphi dll from c #

I have this function defined in delphi code:

procedure TestFLASHWNew( name: array of string; ID: array of Integer; var d1:double ); stdcall; 

How can I define and call it from C #?

+4
source share
2 answers

This is a bit dirty P / Invoke, because you cannot (at best from my admittedly limited knowledge) use any of the built-in simple sorting methods. Instead, you need to use Marshal.StructureToPtr as follows:

WITH#

 [StructLayout(LayoutKind.Sequential)] public struct MyItem { [MarshalAs(UnmanagedType.LPWStr)] public string Name; public int ID; } [DllImport(@"mydll.dll")] private static extern void TestFLASHWNewWrapper(IntPtr Items, int Count, ref double d1); static void Main(string[] args) { MyItem[] items = new MyItem[3]; items[0].Name = "JFK"; items[0].ID = 35; items[1].Name = "LBJ"; items[1].ID = 36; items[2].Name = "Tricky Dicky"; items[2].ID = 37; IntPtr itemsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(MyItem))*items.Length); try { Int32 addr = itemsPtr.ToInt32(); for (int i=0; i<items.Length; i++) { Marshal.StructureToPtr(items[i], new IntPtr(addr), false); addr += Marshal.SizeOf(typeof(MyItem)); } double d1 = 666.0; TestFLASHWNewWrapper(itemsPtr, items.Length, ref d1); Console.WriteLine(d1); } finally { Marshal.FreeHGlobal(itemsPtr); } } 

Delphi

 TItem = record Name: PChar; ID: Integer; end; PItem = ^TItem; procedure TestFLASHWNewWrapper(Items: PItem; Count: Integer; var d1: Double); stdcall; var i: Integer; name: array of string; ID: array of Integer; begin SetLength(name, Count); SetLength(ID, Count); for i := 0 to Count-1 do begin name[i] := Items.Name; ID[i] := Items.ID inc(Items); end; TestFLASHWNew(name, ID, d1); end; 

I implemented it with a wrapper function that calls your TestFLASHWNew function, but you will certainly want to re-process it.

I assumed that you are using Delphi with Unicode strings. If not, change [MarshalAs(UnmanagedType.LPWStr)] to [MarshalAs(UnmanagedType.LPStr)] .

+5
source

Delphi functions have two problems that cause non-Delphi code:

  • It uses Delphi strings, which are a proprietary implementation.
  • It uses open arrays, which again are a proprietary implementation.

Knowing how open arrays are implemented and how the stack is configured to transmit them can allow (it is documented), some “hacks” on the other hand, can be used to read these parameters from the stack. With strings, this is a little trickier because handling them is trickier.

What you can do - if you cannot change the function - is to define a simpler wrapper around this function, which can be called from C # (or any other language), using PChars instead of strings and explicitly passing the dimensions of the array.

+2
source

All Articles