【问题标题】:How to correctly fill and send a dynamic array to a function in c ++ from Delphi如何正确填充动态数组并将其发送到Delphi中的c ++中的函数
【发布时间】:2018-03-31 16:19:36
【问题描述】:

我有以下 c++ 函数:

    public:
__int32 __declspec(dllexport) __stdcall finalizeModelling(
            __int32 model,
            float   * vertices,
            __int32 * indices,
            __int32 FVF
        );

顶点和索引变量是数组。

在德尔福我有:

TFinalizeModelling    = 
function  (AModel : NativeInt; var AVertices : array of TFloat; var AIndices : array of Integer; AFVF : NativeInt) : NativeInt; stdcall;

我尝试使用:

  TFloat = Single;
  PVerticesArray = ^TPVerticesArray;
  TPVerticesArray  = array of TFloat;

  PIndicesArray = ^TPIndicesArray;
  TPIndicesArray  = array of Integer;

TFinalizeModelling    = 
function  (AModel : NativeInt; var AVertices : PVerticesArray ; var AIndices : PIndicesArray ; AFVF : NativeInt) : NativeInt; stdcall;

我已经声明了两个变量:

  vArray: PVerticesArray;
  indices: PIndicesArray;

然后我进行如下函数调用:

  EngineDll.FinalizeModelling(FModel, vArray, indices, 0);

但我遇到了访问冲突。

我的问题是: 在 C++ 中声明和 SetLength 与函数一起使用的动态数组的正确方法是什么?

函数会被多次调用,数组长度不同,内容也不同。

【问题讨论】:

  • 每个参数都被错误地声明了。 C++ int 映射到 Delphi 中的 Integer,并且大概 __int32 扩展为 int。至于数组,将它们声明为指针并传递您的 delphi 数组的第一个元素的地址。最后,这看起来不像是静态方法。是实例方法吗?

标签: c++ arrays delphi


【解决方案1】:

您的大部分声明都不正确。

NativeInt 声明错误。使用Int32Integer

数组的声明可以永远是开放数组(您的第一个声明)或动态数组(您的“答案”)。注意开放数组参数和动态数组只有look相似,其实不然。 (参见Open array parameters and array of const — Confusion

原始声明使用指针,所以也使用指针。您的数组可以是静态的或动态的,但参数声明永远不能。

那就去做吧:

type
  TFinalizeModelling = 
    function(AModel: Int32; 
      AVertices: PSingle; // PSingle = ^Single, declare the type if necessary
      AIndices: PInteger; // PInteger = ^Integer 
      AFVF: Int32): Int32; stdcall;

现在您可以随心所欲了,但请务必将指针传递给数组的第一个元素:

Blah := FinalizeModelling(YourModel, @YourVertices[0], @YourIndices[0], 0);

其中YourVerticesYourIndices 可以是静态或动态数组。


动态数组是 Delphi 特有的类型。它们永远不应跨越 DLL 边界。原始的 C++ 声明没有这样做,但您的翻译会这样做。您的“解决方案”很可能“有效”,但可能会导致引用计数出现问题。

还要注意动态数组变量已经是指针(引用类型)。 从不将 C++ 指针转换为动态数组,并且绝对不能将其转换为指向动态数组的指针

更多信息:Pitfalls of converting

【讨论】:

  • 这很奇怪。你不需要指针数学。您将数组声明为指针并传递数组第一个元素的地址。在 Delphi 代码中,您使用数组语法访问元素。通常这些将是动态数组。传递第一个元素的地址,让接口另一端的代码做它的事情。
  • 它们是否动态数组无关紧要,如果用户分配它们。您确实可以传递第一个元素。但是作为参数类型的动态数组的声明是错误的,尤其是作为一个指针。但你是对的,这可以简化。我会重写的。
  • 我同意所有这些。只是不是需要指针数学的声明。声明任意大尺寸的数组类型也没什么好说的。我们已经使用动态数组多年了。请停止传播这种废话。
  • 对,这样好多了
  • 声明大型静态数组类型仅适用于指针类型(以前的替代方法是 PBla = ^TBla; TBla = array[0..0] of X;,而您使用 PBla 作为参数类型)。如果对方想要访问元素,这是一件好事。但是我忘了另一边是C(或者C++),通过指针访问数组没有问题。
猜你喜欢
  • 2017-08-28
  • 2021-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-27
  • 2015-08-04
相关资源
最近更新 更多