0

所以我在从 C# 调用的 Delphi DLL 中有以下记录结构。

  TItemPic = record
    x, y : Integer;
    id : Integer;
    Hue : Integer;
    Page : Integer;
    ElemNum : Integer;
  end;

  TItemToken =  record
    id : Cardinal;
    Arguments : String;
    ElemNum : Integer;
  end;


  TItemType = record
    ID : Integer;
    Hue : Integer;
    ItemPics : array of TItemPic;
    ItemToken : array of TItemToken;
end;

和功能:

function GetItemInfo(index : Word) : TItemType;

现在我在 C# 中有以下翻译的结构:

    public struct TItemPic
    {
        public int X { get; set; }
        public int Y { get; set; }
        public int ID { get; set; }
        public int Hue { get; set; }
        public int Page { get; set; }
        public int ElemNum { get; set; }
    }

    public struct TItemToken
    {
        public uint ID  { get; set; }
        public TPCharStr Arguments { get; set; }
        public int ElemNum { get; set; }
    }

    public struct TItemType
    {
        public uint ID { get; set; }
        public int Hue { get; set; }
        public TItemPic[] ItemPics { get; set; }
        public TItemToken[] ItemToken { get; set; }
    }


[DllImport("mydelphi.dll", EntryPoint = "GetItemInfo", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]
internal static extern TItemType GetItemInfo(ushort index);

目标是这样的:

TItemType myItem = GetItemInfo(1);

我不确定如何处理 TItemType 记录中的开放数组ItemPics : array of TItemPic;ItemToken : array of TItemToken;

阅读 David Heffernan 的一些答案,我相信我可能应该将这些声明为 IntPtr 然后将数据复制到一个数组中——但是我不确定如何获取存储的元素数量。他指出,Delphi 开放数组将引用计数和数组大小存储在传递的指针的负偏移量处......但我不确定如何检索这些信息并将其转换:-)

4

1 回答 1

3

首先,这些是动态数组而不是开放数组。

您不能将托管 Delphi 类型用于互操作。因此,这里不能使用字符串和动态数组。

对于字符串,您需要在 Delphi 端使用 PWideChar,指向空终止的宽字符数组的指针。在 C# 端,如果将文本传递给 Delphi,则使用字符串,如果文本向另一个方向传递,则使用 StringBuilder。

对于数组,您需要将参数/字段声明为指向元素类型的指针,然后使用指针算法遍历数组。编组器将按值传递指向数组中第一个元素的指针。

您需要在调用 C# 代码中分配所有缓冲区。如果您需要计算缓冲区需要多大,请提供一个提供该信息的函数。

您的另一个问题是您必须使两个函数调用约定匹配。选择 stdcall,这是 C# 端的默认设置。而且你不能从你的 Delphi DLL 返回记录,因为 Delphi 使用非标准 ABI 来处理复杂的返回类型。您必须将记录作为 var 参数传递。

我怀疑编组器不会处理包含非 blittable 结构数组的结构,即使您遵循上面的建议,这也是您所拥有的。就个人而言,我可能会一次要求一个结构并避免复杂的嵌套。概括地说,会有一个名为 GetItemCount 的函数返回项目数。当然,还有一个称为 GetItem 的方法,它通过 var 参数返回第 i 个项目。

于 2013-08-21T09:48:43.277 回答