需要帮助从Delphi正确调用C函数

时间:2011-08-22 11:44:11

标签: c arrays delphi pointers dll

我在Delphi中静态导入动态库(DLL)并尝试访问其功能。

以下是我尝试访问的特定C函数减速度:

int flann_radius_search_double (flann_index_t index_ptr, /* the index */
                                double* query, /* query point */
                                int* indices, /* array for storing the indices found (will be modified) */
                                double* dists, /* similar, but for storing distances */
                                int max_nn,  /* size of arrays indices and dists */
                                float radius, /* search radius (squared radius for euclidian metric) */
                                struct FLANNParameters* flann_params);

这是我在Delphi中的减速:

function flann_radius_search_double(index_ptr: flann_index_t;
  var query: double; var indices: longint; var dists: double;
  max_nn: longint; radius: single; var flann_params: FLANNParameters): longint;
  cdecl; external External_library Name 'flann_radius_search_double';   

我访问了这个函数:

  type
  TDoubleArray = array[0..1000] of double;
  PDoubleArray = ^TDoubleArray;

  TIntArray = array[0..1000] of Integer;
  PIntArray = ^TIntArray;
  ...
  ... <other unrelated code>

  var      
    Indicies:TIntArray;
    PIndicies:PIntArray;
    Dists:TDoubleArray;
    PDists:PDoubleArray;
    ...
  begin
    ...
    PIndicies:=@Indicies;
    PDists   :=@Dists; 

   radius_s:=flann_radius_search_double(idx ,&PMyArray^[0,0],Pindicies^[0],&PDists^[0],1000,10,&DEFAULT_FLANN_PARAMETERS);

它不起作用,看起来很远:*( 我真的很感激一些帮助!

编辑:我修正了双/单错误,但当我尝试使用@Indicies [0]而不是Indicies [0]时,我收到错误:

  

错误:通过var调用arg no。 3必须完全匹配:得到“指针”   预计“LongInt”

2 个答案:

答案 0 :(得分:4)

免责声明:下面的内容是指问题的原始版本在完全更改之前。在原始版本中,浮点参数都是浮点数。我会敦促迈克使用复制/粘贴发布真实代码,以避免浪费人们的时间。

C float相当于Delphi Single,即4字节浮点类型。这是你遇到的主要问题。

我个人会在导入声明中将数组声明为PSingle或PInteger,而不是使用var参数。通过引用传递单个值时,var参数是合适的。

调用函数时,我不会使用固定的尺寸数组。我会使用动态数组和SetLength。然后用PSingle(MyArray)或@MyArray [0]传递数组,无论你喜欢什么。

我更喜欢Integer和Longint,因为我相信Integer最接近C int。

您的数组大小为1001个元素,您只需要它们为1000个。

结构最好通过var传递,就像你在导入声明中一样,但不是你在调用中拥有它。由于您的问题中的代码不完全匹配,我不想再说了什么。

function flann_radius_search_double(
  index_ptr: flann_index_t;
  var query: Single;
  indices: PInteger;
  dists: PSingle;
  max_nn: Integer;
  radius: Single;
  var flann_params: FLANNParameters
): Integer; cdecl; external External_library Name 'flann_radius_search_double';   
...
var
  indices: array of Integer;
  dists: array of Single;
...
SetLength(indices, 1000);
SetLength(dists, 1000);    
radius_s := flann_radius_search_double(
  idx,
  MyArray[0,0],
  @indicies[0],
  @dists[0],
  1000,
  10.0,
  DEFAULT_FLANN_PARAMETERS
);

答案 1 :(得分:2)

在Delphi中,float映射到Single不是 Double。所以它变成了:

function flann_radius_search_double(index_ptr: flann_index_t; 
                                    var query: Single;
                                    indices: PInteger; // array, so NOT a var parameter
                                    dists: PSingle;    // array, so NOT a var parameter 
                                    max_nn: Integer;
                                    radius: Single;
                                    var flann_params: FLANNParameters): Integer; 
   cdecl; etc...

你称之为:

 const
   CArraySize = 1000;

 ...

 var
   Indices: array[0..CArraySize - 1] of Integer;
   Dists: array[0..CArraySize - 1] of Single;
 begin
   ...
   x := flann_radius_search_double(idx, yourQuery, 
          @Indices[0], @Dists[0], Length(Dists), yourRadius, yourFlannParams);