我一直在尝试通过以下方式调用在 Delphi 中创建的方法:
function _Func1(arrParams: array of TParams): Integer;stdcall;
type
TParams = record
Type: int;
Name: string;
Amount : Real;
end;
我的代码是:
[DllImport("some.dll", EntryPoint = "_Func1", CallingConvention = CallingConvention.StdCall)]
public static extern int Func(
[MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.Struct)] TParams[] arrParams)
结构是:
[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct TParams
{
public int Type;
[MarshalAs(UnmanagedType.AnsiBStr)]
public string Name;
public double Amount;
}
当我调用此方法时出现错误: 无法编码类型为“TParams”的字段“名称”:无效的托管/非托管类型组合(字符串字段必须与 LPStr、LPWStr、BStr 或 ByValTStr 配对)。
但是这些组合都不起作用,因为 Delphi 的字符串以其长度为前缀并且它肯定是 Ansi(我已经用其他字符串参数尝试过)。有谁知道如何解决这个问题?
最佳答案
这有两个主要问题,开放数组的使用和 Delphi string
的使用。
开放数组
Delphi 开放数组是通过传递一个指向数组第一个元素的指针和一个指定最后一项索引的额外参数来实现的,在 Delphi 术语中是 high
。有关详细信息,请参阅 this answer .
Delphi 字符串
C# 编码器不能与 Delphi 字符串互操作。 Delphi 字符串是私有(private)类型,只能在 Delphi 模块内部使用。相反,您应该使用以 null 结尾的字符串 PAnsiChar
。
把它们放在一起你可以这样写:
德尔福
type
TParams = record
_Type: Integer;//Type is a reserved word in Delphi
Name: PAnsiChar;
Amount: Double;
end;
function Func(const arrParams: array of TParams): Integer; stdcall;
C#
[StructLayoutAttribute(LayoutKind.Sequential)]
public struct TParams
{
public int Type;
public string Name;
public double Amount;
}
[DllImport("some.dll")]
public static extern int Func(TParams[] arrParams, int high);
TParams[] params = new TParams[len];
...populate params
int retval = Func(params, params.Length-1);
关于c# - 在 C# 中使用 Delphi 的结构数组和字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10584690/