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;
Кажется, отлично работает; и намного быстрее, чем я ожидал.