如何使用C#调用接收Delphi开放数组参数的函数?
如何将Delphi代码转换为C#? 它需要一个array of Byte
,但我不确定C#的等价物是什么。 我的尝试不起作用,并抛出像AccessViolationException之类的exception。
delphi:
function SetLevel(a: array of byte): boolean; stdcall; external 'DMX510.dll';
C#:
[DllImport("DMX510.DLL")] public static extern Boolean SetLevel(Byte[] bytearray); Byte[] byteArray = new Byte[5]; byteArray[1] = 75; SetLevel(byteArray);
Delphi开放数组不是有效的互操作类型。 你不能通过P / invoke轻松地将它与C# byte[]
匹配。 在理想的世界中,本机DLL会暴露不同的接口,但正如您在注释中所述,您无法控制该接口。
但是,您可以欺骗C#代码传递Delphi DLL正确解释的内容,但它有点脏。 关键是声明的Delphi open数组有一个额外的隐式参数,包含数组中最后一个元素的索引。
[DllImport(@"DMX510.DLL")] public static extern bool SetLevel(byte[] byteArray, int high); byte[] byteArray = new byte[] { 0, 75, 0, 0, 0}; SetLevel(byteArray, byteArray.Length-1);
需要说明的是,尽管参数列表看起来如此不同,上面的C#代码将成功调用声明的Delphi DLL函数:
function SetLevel(a: array of byte): boolean; stdcall;
我不知道传递长度为5的数组是否合适,或者你是否真的想将第二项设置为非零值。
这是我成功实现从Delphi和C#发送数组的方式。
C#:
[DllImport("Vendors/DelphiCommunication.dll", CallingConvention = CallingConvention.StdCall)] public static extern void LoadFromFileCHR( string sFileName, ref int iSize, ref double AreaCoef, ref double FWaveLength, ref bool FHasWaveLength, double[] ChromX, double[] ChromY );
请注意, 单个类型具有REF,而数组不具有REF ,但无论如何 ,数组仍将像REF一样工作
delphi:
Type ArrayDouble100k = array [0..99999] of Double; procedure LoadFromFileCHR( FileName : String; var Size : Integer; var AreaCoef : Double; var FWaveLength: Double; var FHasWaveLength : Boolean; var ChromX : ArrayDouble100k; var ChromY : ArrayDouble100k); StdCall; begin //... end; exports LoadFromFileCHR;
请注意, VAR也使用数组参数 (Delphi类似于REF)。
我有各种各样的错误,因为我在C#代码中使用了数组
导致内存损坏的另一个问题是我没注意到这些代码在Delphi和C#中是不一样的:
delphi:
for i := 0 to Length(fileCHR.ChromX) do //This is wrong
C#
for(int i = 0; i < fileCHR.ChromX.Length; i++)
delphi也一样
for i := 0 to Length(fileCHR.ChromX) - 1 do //This is right
如果溢出传递给delphi的数组的边界,它也可能导致各种错误