我正在使用Delphi加载一个dll(我在Delphi XE-3中创建),以便与某些C代码连接。我的问题是搞清楚为什么我的数组没有被传递给c函数 - 他们是唯一没有传递给c函数的人。 delphi文件(简化)如下所示:
program CallcCode
uses
SysUtils, Windows,
DLLUnit in 'DLLUnit.pas'; // Header conversion
var
DLLHandle: cardinal;
n: Integer;
A: TArray<Integer>;
result1: Integer;
begin
// Initialize each Array
SetLength(A,n);
A[0] = ...;
// Load the DLL (and confirm its loaded)
DLLhandle := LoadLibrary('dllname.dll');
if DLLhandle <> 0 then
begin
result1 := dll_func1(n,A); // A and B are not passed correctly
end
FreeLibrary(DLLHandle);
end.
我第一次成功“追踪到”dll_func1,输入DLLUnit,其中包含:
const
nameofDLL = 'dllname';
function dll_func1(n: Integer; A: TArray<Integer>): Integer; cdecl; external nameofDLL;
再次“追踪”,我到达了c文件,它仍然具有正确的n和DLLdefs值,但是A(在“局部变量”标题下)已经变为:
[-] A :(Aplha-Numeric)
..[0] 0 (0x00000000)
我知道我至少正在访问DLL(希望如此),因为其他函数调用正常工作,我能够毫无问题地跟踪到dll_func1.c文件。我尝试将功能更改为
function dll_func1(n: Integer; A: PInteger): Integer; cdecl; external nameofDLL;
...
result1 := dll_func1(n,PInteger(A))
或
function dll_func1(n: Integer; A: PInteger): Integer; cdecl; external nameofDLL;
...
result1 := dll_func1(n,@A[0])
(使用TArray和Integer或A数组)但没有变化,这让我相信这与我没有看到的问题有关。整个事情编译并运行,但是由于TArray失败,result1是不正确的。关于出了什么问题的任何想法?
编辑 C中的函数为:
int dll_func1(int n, int A [])
答案 0 :(得分:4)
您的问题包含两个外部函数的Delphi声明。其中一个使用TArray<T>
作为参数。那是完全错误的。不要那样做。您不能将Delphi动态数组用作互操作类型。原因是TArray<T>
是一个复杂的托管类型,只能由Delphi代码创建和使用。
您需要像我在下面那样做,并且正如我在回答您之前的问题时所解释的那样,并将数组参数声明为指向元素类型的指针。例如,PInteger
,PDouble
等
这里有很多混乱,而且不必要的复杂性。您需要的是最简单的示例,演示如何将数组从Delphi代码传递给C代码。
这是。
C代码
//testarray.c
void printDouble(double d); // linker will resolve this from the Delphi code
void test(double *arr, int count)
{
int i;
for (i=0; i<count; i++)
{
printDouble(arr[i]);
}
}
德尔福代码
program DelphiToC;
{$APPTYPE CONSOLE}
uses
Crtl;
procedure _printDouble(d: Double); cdecl;
begin
Writeln(d);
end;
procedure test(arr: PDouble; count: Integer); cdecl; external name '_test';
{$L testarray.obj}
var
arr: TArray<Double>;
begin
arr := TArray<Double>.Create(1.0, 2.0, 3.0, 42.0, 666.0);
test(PDouble(arr), Length(arr));
Readln;
end.
使用例如Borland C编译器编译C代码,如下所示:
bcc32 -c testarray.c
输出是:
1.00000000000000E+0000 2.00000000000000E+0000 3.00000000000000E+0000 4.20000000000000E+0001 6.66000000000000E+0002
请注意,我静态链接到C代码,因为这对我来说更容易。如果将C代码放在DLL中,则没有太大的变化。
结论是我在回答你之前的答案时给你的代码,我在此重复,这是正确的。该方法成功地将数组从Delphi代码传递给C.看起来您的诊断和调试错误。
您只是在检查A[0]
,所以您只看到一个值就不足为奇了。如果您只查看A[1]
,A[2]
,...,A[n-1]
,您会看到所有值都正确传递。或者,您的调试可能是在使用TArray<T>
作为参数的外部函数的错误声明中执行的。