TDataset -> указатель на строку столбцов матрицы? - PullRequest
0 голосов
/ 20 августа 2011

Я пишу приложение для Windows на Lazarus / FreePascal (например, Delphi). У меня есть TDataset объект, который заполняется 5000 строк, 2 столбца числовых значений. Мне нужно передать эти данные в C функцию, которую я статически импортирую из библиотеки .dll.

Вот выдержка из руководства библиотеки, объясняющая, в каком формате должны быть ее параметры:

flan_index_t flann_build_index(float* dataset,
    int rows,
    int cols,
    float* speedup,
    struct FLANNParameters* flann_params);

Эта функция создает индекс и возвращает ссылку на него. аргументы, ожидаемые этой функцией: набор данных, строки и cols - используются для указания входного набора данных точек: набор данных - указатель на матрицу столбцов строк, хранящуюся в мажорной строке порядок (одна функция в каждом ряду)

Могу ли я просто передать объект TDataSet? Должен ли я сначала что-то с этим сделать, чтобы указатель был в правильной форме?

Ответы [ 3 ]

1 голос
/ 20 августа 2011

Очевидно, что вы не можете передать объект TDataSet.Это объект FreePascal, и функция, кажется, ожидает указатель на float (который, вероятно, является указателем на Single в FreePascal).Вероятно, ожидается двухмерный массив float.Вы должны передать еще один указатель на float, а также указатель на структуру FLANNParameters.

Move() также не будет работать.TDataSet не является массивом.

Полагаю, вам придется объявить массив, как сказал Уве, заполнить его набором данных и передать массив:

type
  PMyFloatArray = ^TFloatArray;
  TMyFloatArray = array[0..4999, 0..1] of Single;

var
  MyArray: PMyFloatArray;
  idx: flan_index_t;

begin
  New(MyArray);
  try

    // Fill array using your TDataSet...
    // set up other parameters... 

    idx := flann_build_index(MyArray, 5000, 2, &speedup, etc...);

    // ...

  finally
    Dispose(MyArray);
  end;
end;     

Бесстыдный плаг

Пожалуйста, прочитайте мою статью о проблемах преобразования статью о преобразовании объявлений функций из C в Delphi (и, вероятно, FreePascal на Win32).Теперь я в этом, вы можете прочитать мою статью Обращаясь к указателям тоже.

1 голос
/ 20 августа 2011

Нет, вы не можете передать набор данных напрямую.Обозначение «набор данных» может подразумевать это, но значение совершенно другое.Вы должны передать указатель на матрицу с плавающей точкой в ​​функцию.Чтобы реализовать это, вы должны объявить массив [0..4999, 0..1] с плавающей точкой (возможно, двойной) и заполнить его из набора данных.

0 голосов
/ 21 августа 2011

Используя решение Руди в качестве основы (спасибо, кстати!), Я придумал это:

 with Datasource1.DataSet do
  begin
    Open;
    First;
    field_count := FieldCount;
    record_count := RecordCount;

    row := 0;
    while not EOF do
    begin
      for col := 0 to field_count - 1 do
        MyArray[row, col] := Fields.Fields[col].AsFloat;
      row := row + 1; //Shift to next row in array
      Next; //Shift to next row in dataset
    end;
  end; 

Кажется, отлично работает; и намного быстрее, чем я ожидал.

...