指针和数组从C++到Delphi的转换

指针和数组从C++到Delphi的转换,c++,arrays,delphi,pointers,C++,Arrays,Delphi,Pointers,我试图在我的Delphi代码中使用ANN库.dll。该库是用C++编写的,虽然数据类型相当简单,但我遇到了一些麻烦。 我曾经把C++头文件转换到我能得到的地方。我最后得到了下面的数据类型C++,右边是Delphi: 枚举ANNbool{ANNfalse=0,ANNtrue=1};->ANNbool=longint; typedef-double-ANNcoord;->ANNcoord=双精度; typedef double ANNdist;->ANNdist=双精度; typedef int A

我试图在我的Delphi代码中使用ANN库.dll。该库是用C++编写的,虽然数据类型相当简单,但我遇到了一些麻烦。

我曾经把C++头文件转换到我能得到的地方。我最后得到了下面的数据类型C++,右边是Delphi:

枚举ANNbool{ANNfalse=0,ANNtrue=1};->ANNbool=longint; typedef-double-ANNcoord;->ANNcoord=双精度; typedef double ANNdist;->ANNdist=双精度; typedef int ANNidx;->ANNidx=长型; typedef ANNcoord*ANNpoint;->ANNpoint=^ANNcoord; typedef ANNpoint*ANNpointArray;->ANNpointArray=^ANNpoint; typedef ANNdist*ANNdistArray;->ANNdistArray=^ANNdist; 类型定义ANNidx*ANNidxArray;->ANNidxArray=^ANNidx; 对于初学者,我想成功地移植ANN库中包含的示例。此示例的C++代码是如果你想要评论,只需从Ann的网页下载图书馆。 更具体地说,下面是我在C++代码中遇到的问题: ... 而nPts>p[i]返回false; } 返回true; } stackoverflow上的一名成员帮助我对readPt函数进行了部分转换-但我不确定它是否完全正确的Delphi代码..:

函数readPtinStr:TStream;p:ANNpoint:boolean; 变量 大小:longint;//要读取的字节数 开始 仪表尺寸:=尺寸FannCoord*dim; 结果:=inStr.Readp^,Size=Size; 终止 下面是我在Delphi中实现while循环的失败尝试,该循环忽略了与Delphi无关的代码:

变量 dataPts:AnnPointArray; BinStream:TMemoryStream; dim、maxPts、NPT:长型; 开始 尺寸:=2; 最大值:=1000; dataPts:=annAllocPtsmaxPts,dim; //生成TStream数据 /////////////////////////// BinStream:=TMemoryStream.Create; BinStream.SetSize1001; 对于NPT:=0至1000 do 开始 BinStream.WritenPts,1; 终止 BinStream.Position:=0 /////////////////////////// 净现值:=0; 而NPT 如果有人能抽出时间来帮助我,我将不胜感激

<>编辑:对于AcalLoopts的C++函数来说很重要。这是:

ANNpointArray annAllocPtsint n,int dim//在dim中分配n个pts { ANNpointArray pa=new ANNpoint[n];//分配点 ANNpoint p=new ANNcoord[n*dim];//为坐标分配空间 对于int i=0;i 功能annAllocPtsn:longint;dim:longint:ANNpointArray-cdecl; 外部“ANN.dll”索引33; 编辑2:我仍然无法正确填充输入流,我想

变量 这双:双; 开始 binstream:=TMemoryStream.Create; 该双精度:=1.001; 对于NPT:=0到maxPts*dim do 开始 binstream.WriteThisDouble,大小为该值的两倍; 终止 位置:=0; 净现值:=0; 而NPT您的代码调用DLL函数来分配一个由1000个双精度的2元素数组组成的数组。然后用1001字节填充一个流。您试图用1001字节的数据填充16000字节的存储空间

此外,您放入流中的数据不会形成有意义的双值


另外,您的readPt版本是错误的。您正在分配inStr.Size,而不是本地大小变量。编译器应该警告您,大小是在未初始化的情况下使用的。您的代码会将输入流截断为一个数组段的长度,然后尝试从流中读取未知数量的字节。使用。

您的代码调用DLL函数来分配1000个双精度的2元素数组。然后用1001字节填充一个流。您试图用1001字节的数据填充16000字节的存储空间

此外,您放入流中的数据不会形成有意义的双值

另外,您的readPt版本是错误的。您正在分配inStr.Size,而不是本地大小变量。编译器应该警告您,大小是在未初始化的情况下使用的。您的代码的作用是将输入流截断为一个数组段的长度,然后尝试从数组中读取未知数量的字节
流动使用。

readPt中的代码是正确的。但是它一次读取不止一个,就像其他问题中的C++例子一样。 您的问题是,您将maxPts=1000 double写入内存流,但在maxPts=1000迭代的循环中,每次迭代读取dim=2 double readPt reads dim ANNcoords一次性完成,因此您尝试读取1000*2 ANNcoords,并在到达终点之前用完数据。您应该检查循环中readPt的返回值,如果为false,则中断:

nPts:=0;
while nPts < maxPts do
begin
  if not readPt(BinStream, dataPts[nPts]) then
    Break;
  nPts:=nPts+1;
end;

当然,您也可以将dim*maxPts项写入内存流。

readPt中的代码是正确的。但是它一次读取不止一个,就像其他问题中的C++例子一样。 您的问题是,您将maxPts=1000 double写入内存流,但在maxPts=1000迭代的循环中,每次迭代读取dim=2 double readPt reads dim ANNcoords一次性完成,因此您尝试读取1000*2 ANNcoords,并在到达终点之前用完数据。您应该检查循环中readPt的返回值,如果为false,则中断:

nPts:=0;
while nPts < maxPts do
begin
  if not readPt(BinStream, dataPts[nPts]) then
    Break;
  nPts:=nPts+1;
end;


当然,您也可以将dim*maxPts项写入内存流。

首先,您需要在将流填充到BinStream后将其位置设置回开头。位置:=0@Nat明白了;固定的仍然是相同的错误:-/@Nat我认为我的主要困惑点是访问dataPtsAlso的nPtsth元素,您是否应该在inStr.size:=SizeOfANNcoord*dim;中设置流大小;?我本以为这行应该是Size:=SizeOfAnnCoord*dim;是的,我明白了,我只是想理解代码,这些都是很早就跳出来的东西…首先,你需要在填充完BinStream后将流的位置设置回开始位置。位置:=0@Nat明白了;固定的仍然是相同的错误:-/@Nat我认为我的主要困惑点是访问dataPtsAlso的nPtsth元素,您是否应该在inStr.size:=SizeOfANNcoord*dim;中设置流大小;?我本以为这行应该是Size:=SizeOfAnnCoord*dim;是的,我明白了,我只是想弄明白代码的意思,这些都是很早就跳出来的东西…谢谢,罗伯,正是我所看到的。@罗伯谢谢你,罗伯,这绝对让我明白了。令人尴尬的是,我仍然无法填充流,然后将其写入指针。我更新了我的问题。。我走对了吗?是的,看起来不错。现在看来,这最终有点毫无意义;您将一组数据放入流缓冲区,然后立即将其读回并放入数组中。也可以直接将数据存储在数组中并跳过流。@Rob这绝对没有意义。我只是想了解这一点,这样我才能继续。我真正需要的是用内存中的数据库填充数组。@Rob我仍然无法获得它,以避免在尝试访问dataPts[任何内容]时崩溃。这在我看来是不对的。。。。。此数据类型不是数组,它只是一个指针。@Nat关于使数组静止的说法正确吗?谢谢,罗伯,正是我所看到的。@Rob谢谢你,罗伯,这确实为我澄清了问题。令人尴尬的是,我仍然无法填充流,然后将其写入指针。我更新了我的问题。。我走对了吗?是的,看起来不错。现在看来,这最终有点毫无意义;您将一组数据放入流缓冲区,然后立即将其读回并放入数组中。也可以直接将数据存储在数组中并跳过流。@Rob这绝对没有意义。我只是想了解这一点,这样我才能继续。我真正需要的是用内存中的数据库填充数组。@Rob我仍然无法获得它,以避免在尝试访问dataPts[任何内容]时崩溃。这在我看来是不对的。。。。。此数据类型不是数组,它只是一个指针。@Nat将数组设置为静态是否正确?非常感谢-我想我已经差不多做到了。你能看看我最近在问题底部的编辑吗?我觉得不错。作为一个简单的测试,我将亲自编写一个函数writePt,并在readPt之后对其进行建模,但方向相反。然后我将创建一个二维坐标数组,并借助writePt将其保存在一个循环中。然后我将从流中读取这些数据,并将它们写入另一个数组,然后进行比较。嗯,我对它进行了测试,并成功地将双倍数据写入内存流。如果不是readPtBinStream,dataPts[nPts],我就不能让这个语句工作……据我所知,这是因为dataPts不是数组,不能像dataPts[nPts]那样被引用。SIGSEGV错误具体发生在此时。如果我试图从DATAPT[ODAT]访问数据,我会得到那个错误。C++和C++中,你可以。在较新的Delphis中,您也可以使用指针数学作为数组访问它。在FreePascal中,只需将其声明为ANNcoo的类型TANNcoordArray=array[0..SomeBigNumber-1]
rd;PannCoorArray=^TannCoorArray;。现在,您可以为它获取内存,并将您的PannCordArray用作数组。非常感谢-我想我几乎已经获得了它。你能看看我最近在问题底部的编辑吗?我觉得不错。作为一个简单的测试,我将亲自编写一个函数writePt,并在readPt之后对其进行建模,但方向相反。然后我将创建一个二维坐标数组,并借助writePt将其保存在一个循环中。然后我将从流中读取这些数据,并将它们写入另一个数组,然后进行比较。嗯,我对它进行了测试,并成功地将双倍数据写入内存流。如果不是readPtBinStream,dataPts[nPts],我就不能让这个语句工作……据我所知,这是因为dataPts不是数组,不能像dataPts[nPts]那样被引用。SIGSEGV错误具体发生在此时。如果我试图从DATAPT[ODAT]访问数据,我会得到那个错误。C++和C++中,你可以。在较新的Delphis中,您也可以使用指针数学作为数组访问它。在FreePascal中,只需将其声明为ANNcoord的类型TANNcoordArray=array[0..SomeBigNumber-1];PannCoorArray=^TannCoorArray;。现在您可以为它获取mem内存,并将您的panncordarray用作数组。