Я пытаюсь использовать библиотеку ANN
( приблизительный ближайший сосед ) (.dll) в моем коде Delphi.Библиотека написана на C ++, и, хотя типы данных довольно просты, у меня возникают некоторые проблемы.
Я использовал h2pas для преобразования заголовочного файла C ++ настолько, насколько я мог.Я получил следующие типы данных (C ++ слева, Delphi справа):
enum ANNbool {ANNfalse = 0, ANNtrue = 1}; --> ANNbool = longint;
typedef double ANNcoord; --> ANNcoord = double;
typedef double ANNdist; --> ANNdist = double;
typedef int ANNidx; --> ANNidx = longint;
typedef ANNcoord* ANNpoint; --> ANNpoint = ^ANNcoord;
typedef ANNpoint* ANNpointArray; --> ANNpointArray = ^ANNpoint;
typedef ANNdist* ANNdistArray; --> ANNdistArray = ^ANNdist;
typedef ANNidx* ANNidxArray; --> ANNidxArray = ^ANNidx;
Для начала я хочу успешно портировать образец, включенный в библиотеку ANN
.Код C ++ для этого примера связан здесь без комментариев (если вы хотите получить комментарии, просто загрузите библиотеку с веб-страницы ANN).
Более конкретно, вот отрывок, который явозникли проблемы с (C ++ code ..):
...
while (nPts < maxPts && readPt(*dataIn, dataPts[nPts])) nPts++;
...
bool readPt(istream &in, ANNpoint p)
{
for (int i = 0; i < dim; i++) {
if(!(in >> p[i])) return false;
}
return true;
}
Член в stackoverflow помог мне с частичным преобразованием функции readPt
- но я не уверен, что она полностью верна (код Delphi..):
function readPt(inStr: TStream; p: ANNpoint): boolean;
var
Size: longint; // number of bytes to read
begin
inStr.Size := SizeOf(ANNcoord) * dim;
Result := inStr.Read(p^, Size) = Size;
end;
Вот моя неудачная попытка реализовать этот цикл while
в Delphi (нерелевантный код опущен):
var
dataPts: AnnPointArray;
BinStream: TMemoryStream;
dim,maxPts,nPts: LongInt;
begin
dim := 2;
maxPts := 1000;
dataPts := annAllocPts(maxPts, dim);
//GENERATE TStream data
///////////////////////////
BinStream := TMemoryStream.Create;
BinStream.SetSize(1001);
for nPts := 0 to 1000 do
begin
BinStream.Write(nPts, 1);
end;
BinStream.Position := 0
///////////////////////////
nPts:=0;
while nPts < maxPts do
begin
readPt(BinStream, dataPts[nPts]);
nPts:=nPts+1;
end;
end;
Когда я пытаюсь запустить это, я получаю ошибка сегментации в readPt(BinStream, dataPts[nPts]);
Я буду чрезвычайно признателен, если кто-нибудь найдет время, чтобы помочь мне здесь!
Редактировать: В случае, если важна функция C ++ для annAllocPts()
.. вот она:
ANNpointArray annAllocPts(int n, int dim) // allocate n pts in dim
{
ANNpointArray pa = new ANNpoint[n]; // allocate points
ANNpoint p = new ANNcoord[n*dim]; // allocate space for coords
for (int i = 0; i < n; i++) {
pa[i] = &(p[i*dim]);
}
return pa;
}
А вот как я это реализовал:
function annAllocPts(n: longint; dim: longint): ANNpointArray cdecl;
external 'ANN.dll' index 33;
Редактировать 2: У меня все еще проблемы с заполнением входного потока (я думаю) ...
var
ThisDouble: Double;
begin
binstream := TMemoryStream.Create;
ThisDouble :=1.001;
for nPts := 0 to maxPts*dim do
begin
binstream.Write(ThisDouble,SizeOf(ThisDouble));
end;
BinStream.Position := 0;
nPts:=0;
while nPts < maxPts do
begin
if not readPt(BinStream, dataPts[nPts]) then
Break;
nPts:=nPts+1;
end;