gpt4 book ai didi

c - Delphi-to-C dll : Passing Arrays

转载 作者:太空宇宙 更新时间:2023-11-04 01:34:24 24 4
gpt4 key购买 nike

我正在使用 Delphi 加载一个 dll(我在 Delphi XE-3 中创建的),以便与某些 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 和整数或 A 数组)但没有变化,这让我相信这与我没有看到的问题有关。整个过程编译并运行,但由于 TArray 失败,结果 1 不正确。对出了什么问题有什么想法吗?

编辑 C 中的函数为:

int dll_func1(int n, int A [])

最佳答案

您的问题包含两个外部函数的 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> 的外部函数的错误声明上进行的作为参数。

关于c - Delphi-to-C dll : Passing Arrays,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17240721/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com