Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi DLL函数将带有开放数组的记录返回给C#应用程序_C#_Delphi_Dll_Record - Fatal编程技术网

Delphi DLL函数将带有开放数组的记录返回给C#应用程序

Delphi DLL函数将带有开放数组的记录返回给C#应用程序,c#,delphi,dll,record,C#,Delphi,Dll,Record,因此,我在Delphi DLL中有以下记录结构,我从C#调用它 和功能: function GetItemInfo(index : Word) : TItemType; 现在我用C#翻译了以下结构: 目标如下: TItemType myItem = GetItemInfo(1); 我不确定如何处理TItemType记录ItemPics:TItemPic的数组中的开放数组和ItemToken:TItemToken的数组 阅读David Heffernan的一些答案,我认为我可能应该将这些声明为

因此,我在Delphi DLL中有以下记录结构,我从C#调用它

和功能:

function GetItemInfo(index : Word) : TItemType;
现在我用C#翻译了以下结构:

目标如下:

TItemType myItem = GetItemInfo(1);
我不确定如何处理TItemType记录
ItemPics:TItemPic的数组中的开放数组
ItemToken:TItemToken的数组


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

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

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

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

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

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

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


我怀疑封送拆收器不会处理包含不可blittable结构数组的结构,即使您遵循上述建议,也会处理不可blittable结构数组。就我个人而言,我可能会一次要求一个结构,并避免复杂的嵌套。在大纲中,将有一个名为GetItemCount的函数返回项目数。其中一个叫做GetItem,通过var参数返回第i项。

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

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

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

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

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

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

我怀疑封送拆收器不会处理包含不可blittable结构数组的结构,即使您遵循上述建议,也会处理不可blittable结构数组。就我个人而言,我可能会一次要求一个结构,并避免复杂的嵌套。在大纲中,将有一个名为GetItemCount的函数返回项目数。其中一个名为GetItem,通过var参数返回第i项

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