Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use C# to call a function that receives a Delphi open-array parameter?

Tags:

c#

pinvoke

delphi

How do I convert the Delphi code into C#? It takes an array of Byte, but I'm not sure what the C# equivalent is. My attempt doesn't work and throws exceptions like AccessViolationException.

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);
like image 964
Pascal Bayer Avatar asked Oct 30 '11 10:10

Pascal Bayer


1 Answers

A Delphi open array is not a valid interop type. You can't easily match that up with a C# byte[] through a P/invoke. In an ideal world a different interface would be exposed by the native DLL but as you have stated in comments, you do not have control over that interface.

However, you can trick the C# code into passing something that the Delphi DLL will interpret correctly, but it's a little dirty. The key is that a Delphi open array declared like that has an extra 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, in spite of the parameter lists looking so different, the C# code above will successfully call the Delphi DLL function declared so:

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

I have no idea whether or not passing an array of length 5 is appropriate, or whether you really meant to just set the second item to a non-zero value.

like image 169
David Heffernan Avatar answered Nov 14 '22 22:11

David Heffernan