从Delphi调用C#DLL中的函数时,参数停留在单个值上

7lrncoxx  于 2022-10-16  发布在  C#
关注(0)|答案(1)|浏览(162)

我有一个带有几个导出函数的C#DLL。在其中一个函数上,当从我们的Delphi XE2应用程序调用它时,数组的长度参数在DLL中始终读取为31,无论我实际传递的是什么。
C#函数声明

[DllExport(CallingConvention = CallingConvention.StdCall)]
public static bool FraDataRead(int dbHash, uint pointid, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] Double[] FraData, int length)

Delphi函数声明

TGetFraData = function(dbHash         : Integer;
                       pointid        : Uint32;
                       unmanagedArray : Array of Double;
                       arraySize      : Integer) : Bool; stdcall;

获取程序

GetFraData : TGetFraData; //this is a class variable, here for simplicity 
@GetFraData := GetProcAddress(FDllHandle, 'FraDataRead');

调用函数

function TIviumSQLAccess.IviFraData(const PointId : Uint32;
                     const FraData : Array of Double;
                     const arraySize : Integer): Boolean;
begin
  Result := GetFraData(dbHash,
                    PointId,
                    FraData,
                    arraySize);
end;

我已经测试了从另一个C#应用程序调用该函数,并且长度参数的功能与预期一致。当从Delphi调用时,它总是以32作为长度(当前)调用,但DLL总是处理31。我打大号和小号都试过,但总是用31。

sz81bmfz

sz81bmfz1#

TGetFraData = function(dbHash         : Integer;
                       pointid        : Uint32;
                       unmanagedArray : Array of Double;
                       arraySize      : Integer) : Bool; stdcall;

此代码是错误的,因为它使用了Delphi开放数组。它们实际上被实现为两个参数,指向数组的指针和最后一个元素的索引,这就是为什么您看到长度为32的数组的索引为31。
相反,您需要像这样声明该类型

TGetFraData = function(dbHash         : Integer;
                       pointid        : Uint32;
                       unmanagedArray : PDouble;
                       arraySize      : Integer) : Bool; stdcall;

然后将指针传递给数组的第一个元素。

相关问题