TDataset -> указатель на строку столбцов матрицы?

Я пишу приложение для 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);

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

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

3 ответа

Решение

Очевидно, вы не можете передать TDataSet объект. Это объект FreePascal, и функция, кажется, ожидает указатель на float (который, вероятно, является указателем на Single в FreePascal). Это, вероятно, ожидает двумерный массив float"S. Вы должны передать еще один указатель на 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). Теперь я в этом, вы можете прочитать мою статью Обращаясь к указателям тоже.

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

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

 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; 

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

Другие вопросы по тегам