I have a C# DLL with several exported functions. On one of these functions, when calling it from our Delphi XE2 application the length parameter for the array is always read as 31 in the DLL, regardless of what I actually pass.
The C# function declaration
[DllExport(CallingConvention = CallingConvention.StdCall)]
public static bool FraDataRead(int dbHash, uint pointid, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] Double[] FraData, int length)
Delphi function declaration
TGetFraData = function(dbHash : Integer;
pointid : Uint32;
unmanagedArray : Array of Double;
arraySize : Integer) : Bool; stdcall;
Getting the procedure
GetFraData : TGetFraData; //this is a class variable, here for simplicity
@GetFraData := GetProcAddress(FDllHandle, 'FraDataRead');
Calling function
function TIviumSQLAccess.IviFraData(const PointId : Uint32;
const FraData : Array of Double;
const arraySize : Integer): Boolean;
begin
Result := GetFraData(dbHash,
PointId,
FraData,
arraySize);
end;
I have tested calling the function from another C# application, and there the length parameter functions as expected. When calling from Delphi it always calls with 32 as the length (currently) but the DLL always process 31. I have tried both larger and smaller numbers when calling, but it always uses 31.
CodePudding user response:
TGetFraData = function(dbHash : Integer;
pointid : Uint32;
unmanagedArray : Array of Double;
arraySize : Integer) : Bool; stdcall;
This code is wrong because it uses a Delphi open array. These are actually implemented as two arguments, the pointer to the array, and the index of the last element, which is why you see a 31 for your array of length 32.
You need instead to declare the type like this
TGetFraData = function(dbHash : Integer;
pointid : Uint32;
unmanagedArray : PDouble;
arraySize : Integer) : Bool; stdcall;
and then pass a pointer to the first element of the array.