【问题标题】:C# Struct to delphi packed recordC# Struct 到 delphi 打包记录
【发布时间】:2015-06-02 13:38:37
【问题描述】:

我有一个从 delphi dll 中提取的函数

function func_name(par1: Byte; par2: struct1) : boolean

结构 1 由:

struct1 = packed record
    Number: Byte;
    arrStr : array[1..8] of struct2;
end

而且struct2由以下部分组成:

struct2 = packed record
    Code: Byte;
    Price: Single;
end

现在使用 C# 我正在尝试使用以下方法将相同时间的结构传递给 delphi

首先我创建了我的结构:

[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
public struct struct2
{
    public byte code;
    public Single price;
}

[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
public struct struct1
{
    public byte Number;

    [MarshalAs(UnmanagedType.LPArray)]
    public struct2[] Prices;

    public struct1(int elements)
    {
        Number = 0;
        arrStr = new struct2[elements];
    }
}

注意elements 始终为 8。

所以当我尝试运行代码从而填充数组并将其传递给函数时,我得到以下错误:

Invalid managed/unmanaged type combination (Array fields must be paired with ByValArray or SafeArray)."

【问题讨论】:

  • @Jerry 不,没有
  • @David 这就是为什么我在看到您的回答后立即删除了我的评论(发布后几秒钟)。我只记得很多类似的案例,这些案例都是通过不使用“打包”记录而仅使用普通记录来解决的。
  • @Jerry 重要的是双方匹配。

标签: c# delphi pinvoke


【解决方案1】:

数组在结构中是内联的。它不是指针。所以不是

[MarshalAs(UnmanagedType.LPArray)]

你必须使用

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]

【讨论】:

  • 干得好!它工作得很好!我试过 byValArray 但没有定义大小!再次感谢!
  • FWIW 文档说:当 MarshalAsAttribute.Value 属性设置为 ByValArray 时,必须设置 SizeConst 字段以指示数组中的元素数。当需要区分字符串类型时,ArraySubType 字段可以选择包含数组元素的 UnmanagedType。您只能在其元素在结构中显示为字段的数组上使用此 UnmanagedType。 您可以忽略最后一句中的语法错误!!
  • 非常感谢@david
猜你喜欢
  • 1970-01-01
  • 2018-04-19
  • 1970-01-01
  • 1970-01-01
  • 2013-10-17
  • 2012-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多