如何在C#中的delphi dll中调用此函数

man*_*ans 4 c# delphi dll pinvoke

我在delphi代码中定义了这个函数:

procedure TestFLASHWNew(
    name: array of string; 
    ID: array of Integer;
    var d1:double
); stdcall;
Run Code Online (Sandbox Code Playgroud)

如何从C#定义和调用它?

Dav*_*nan 5

这是一个混乱的P/Invoke,因为你不能(尽管我公认的有限的知识)使用任何内置的简单编组技术.相反,你需要Marshal.StructureToPtr像这样使用:

C#

[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);
    }
}
Run Code Online (Sandbox Code Playgroud)

德尔福

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;
Run Code Online (Sandbox Code Playgroud)

我用一个调用你的TestFLASHWNew函数的包装函数来实现它,但你无疑会想要重新编写它.

我假设您正在使用带有Unicode字符串的Delphi.如果没有,那么[MarshalAs(UnmanagedType.LPWStr)]改为[MarshalAs(UnmanagedType.LPStr)].