开发者

Need help properly calling a C function from Delphi

开发者 https://www.devze.com 2023-03-29 23:58 出处:网络
I am statically importing a dynamic library (DLL) within Delphi and attempting to access its functions.

I am statically importing a dynamic library (DLL) within Delphi and attempting to access its functions.

Here is the specific C function deceleration that I am trying to access:

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);

Here is my deceleration in 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';   

And I accessed the function like this:

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

  TIntArray = array[0..1000] of Integer;
  PIntArr开发者_如何学Goay = ^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);

It is not working, and looks way off :*( I would really appreciate some assistance!

Edit: I fixed the double/single mistake, but when I attempt to use @Indicies[0] instead of Indicies[0] I get an error:

Error: Call by var for arg no. 3 has to match exactly: Got "Pointer" expected "LongInt"


Disclaimer: what is written below refers to the original version of the question before it was completely changed. In the original version the floating point parameters were all float. I would urge Mike to post the real code using copy/paste in order to avoid wasting people's time.

C float is equivalent to Delphi Single, the 4 byte floating point type. That's the main problem you have.

I personally would declare the arrays as PSingle or PInteger in the import declaration, rather than using var parameters. When passing single values by reference then var parameters is appropriate.

When calling the function I wouldn't use fixed dimensioned arrays. I would use dynamic arrays and SetLength. Pass the array then with PSingle(MyArray), or @MyArray[0], whichever you prefer.

I would prefer Integer to Longint since I believe that Integer most closely matches C int.

Your arrays are 1001 elements in size, you only need them to be 1000.

The struct is best passed by var as you have it in the import declaration, but not as you have it in the call. Since the code in your question doesn't quite match up I don't want to say anything more.

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
);


In Delphi, float maps to Single, not Double. So it becomes:

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...

You call it like:

 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);
0

精彩评论

暂无评论...
验证码 换一张
取 消