Нужна помощь, чтобы правильно вызвать функцию C из Delphi - PullRequest
1 голос
/ 22 августа 2011

Я статически импортирую динамическую библиотеку (DLL) в Delphi и пытаюсь получить доступ к ее функциям.

Вот конкретное замедление функции 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 для аргумента №. 3 должен точно соответствовать: получил "Указатель" ожидаемый "LongInt"

Ответы [ 2 ]

4 голосов
/ 22 августа 2011

Отказ от ответственности: то, что написано ниже, относится к исходной версии вопроса до того, как он был полностью изменен.В оригинальной версии все параметры с плавающей точкой были плавающими.Я бы посоветовал Майку опубликовать реальный код, используя копирование / вставку, чтобы не тратить время людей.

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
);
2 голосов
/ 22 августа 2011

В 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...