c - 通过引用将双数组从 C 传递到 Delphi DLL

标签 c arrays delphi dll

我们正在为我们的 Delphi (XE5) 应用程序开发一个 API。为了将来自 Delphi DLL 函数的数据与主程序(基于 C;(控制台)C 或 C++ 代码应用程序或 Matlab 和 Simulink)进行通信,调用者分配的数组需要由 DLL 填充 double 值。

我知道开放式数组(Delphi 特定的)对于这个目的不是很方便,因为它们包含你必须在 C 中模拟的额外数据。相反,我打算使用指针算法(参见 dll 函数:inc (APDouble)) 通过直接指向正确的地址。我的问题是,你们的软件开发人员是否会这样做。

下面包含一个演示(完整来源)。

DLL(在 DXE5 中制作):

library PDA;

uses
  System.StrUtils,
  System.SysUtils,
  Vcl.Dialogs;

{$R *.res}

function ShowArrayContents( APDouble: PDouble;
                            size: Integer): integer; cdecl; export;
var
  i: Integer;
begin
  Result := 0;
  for i := 0 to size-1 do
  begin
    // Show value!
    MessageDlg(Format('%p -> %p -> %f', [@APDouble, APDouble, APDouble^]), mtWarning, [mbOK], 0);
    Inc(APDouble);
  end;
end;

exports
  ShowArrayContents;

begin

end.

C 代码调用程序(在 C++ 构建器 XE4 中制作):

#include <stdio.h>
#include <tchar.h>
#include <stdlib.h>
#include <windows.h>

typedef int (*_ShowArrayContents) (double *, int);

char *dllname = "PDA.dll";
static HINSTANCE hInstanceControl;

_ShowArrayContents ShowArrayContents = NULL;

int _tmain(int argc, _TCHAR* argv[])
{
    double DVals[3] = {1.23, 4.56, 7.89};
    int i;

    hInstanceControl = LoadLibrary(dllname);

    if( hInstanceControl != NULL){
        ShowArrayContents =(_ShowArrayContents)GetProcAddress(hInstanceControl, "ShowArrayContents");
    } else {
        return 0;
    }

    // test program:
    (*ShowArrayContents)(&DVals[0], 3);

    FreeLibrary(hInstanceControl);

    system("pause");
    return 0;
}

最佳答案

您的代码运行良好,但正如您所观察到的那样,它很笨拙。对于这样的互操作,我会硬着头皮使用 $POINTERMATH指示。这使您可以像对待数组一样对待指针,就像在 C 或 C++ 中所做的那样。例如:

{$POINTERMATH ON}
function GetSum(arr: PDouble; len: Integer): Double; cdecl; 
var
  i: Integer;
begin
  Result := 0.0;
  for i := 0 to len-1 do
    Result := Result + arr[i];
end;

另一种选择是复制到 native Delphi 数组并将其用于后续处理。显然这涉及副本,但有时这正是您想要的。在这种情况下,您可以这样做:

var
  x: TArray<Double>;
....
SetLength(x, len);
Move(arr^, Pointer(x)^, len*SizeOf(arr^));

或者,如果您不喜欢使用 Move,一个很好的旧循环:

{$POINTERMATH ON}
var
  i: Integer;
  x: TArray<Double>;
....
SetLength(x, len);
for i := 0 to len-1 do
  x[i] := arr[i];

关于c - 通过引用将双数组从 C 传递到 Delphi DLL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23294802/

相关文章:

c - 当我执行 printf ("%d",'=' +'=' ); 时,为什么它显示 122。请详细解释

javascript - 仅最后一项添加到映射函数内的数组中

delphi - Delphi 库的路径

c# - 断言在库初始化期间未被 except block 捕获

C - 将 argv 的值分配给变量

你能解释一下以下 C 代码的输出吗?

php - 使用 file() 函数的 Foreach 连续循环。

jquery - 我无法获取 KEY : VALUE after paring a message string

Delphi RTTI故障: GetPropInfo returns nil with {$METHODINFO ON}?

c - 如何去除 "bash"中对 "C"有特殊意义的字符串中的标点符号