How to use C # to call a function that receives a Delphi Open array parameter?

How to convert Delphi code to C #? An array of Byte required, but I'm not sure what the equivalent of C # is. My attempt fails and throws exceptions such as AccessViolationException.

Delphi:

 function SetLevel(a: array of byte): boolean; stdcall; external 'DMX510.dll'; 

FROM#:

 [DllImport("DMX510.DLL")] public static extern Boolean SetLevel(Byte[] bytearray); Byte[] byteArray = new Byte[5]; byteArray[1] = 75; SetLevel(byteArray); 
+4
source share
2 answers

An open Delphi array is not a valid interop type. You cannot easily match this with C # byte[] using P / invoke. In an ideal world, another interface will be displayed on the native DLL, but, as you said in the comments, you have no control over this interface.

However, you can trick C # code into passing something that the Delphi DLL will interpret correctly, but it's a little messy. The key is that the Delphi public array declared in this way has an additional implicit parameter containing the index of the last element in the array.

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

To be clear, even though the parameter list looks different, the above C # code successfully calls the Delphi DLL function, declared like this:

 function SetLevel(a: array of byte): boolean; stdcall; 

I have no idea if an array of length 5 is suitable, or if you really want to just set the second element to a nonzero value.

+7
source

This is how I successfully implemented sending arrays from and to Delphi and C #.

FROM#:

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

Note that single types have REF and arrays DO NOT have REF , but arrays will work as REF anyway

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; 

Note that VAR also has Array parameters (similar to Delphi REF).

I had all kinds of errors because I had a ref with arrays in C # code

Another problem that caused memory corruption for me was that I did not notice that these codes did not match Delphi and C #:

Delphi:

 for i := 0 to Length(fileCHR.ChromX) do //This is wrong 

FROM#

 for(int i = 0; i < fileCHR.ChromX.Length; i++) 

The same thing in delphi would be

 for i := 0 to Length(fileCHR.ChromX) - 1 do //This is right 

If you overflowed the boundaries of arrays passed to delphi, this could also cause all kinds of errors

0
source

All Articles