从C指针和数组的转换++德尔福 [英] Conversion of pointers and arrays from C++ to Delphi

查看:199
本文介绍了从C指针和数组的转换++德尔福的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用 ANN 我的德尔福code内近似近邻)库(.dll文件)。该库是用C ++,虽然数据类型是相当简单的,我有一些麻烦。

我用 h2pas 到C ++头文件转换据我可以得到它。我结束了以下数据类型(C ++左侧,德尔福在右侧):

枚举ANNbool {ANNfalse = 0,ANNtrue = 1}; - > ANNbool = Longint型;
双的typedef ANNcoord; - > ANNcoord =双;
双的typedef ANNdist; - > ANNdist =双;
的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 ++的code这个样品是此处链接没有评论(如果你想的意见,只要下载库从ANN的网页)。

更确切地说,这里要说的是,我遇到的麻烦的摘录(C ++ code ..):

...
而(NPTS< maxPts&放大器;&安培; readPt(* DATAIN,dataPts [NPTS))NPTS ++;
...
布尔readPt(istream的&安培;中,ANNpoint P)
{
 的for(int i = 0; I<暗淡;我++){
 如果((在&G​​T;!指p [i]))返回false;
 }
 返回true;
}

这是计算器的成员帮助我与 readPt 函数的局部转换 - 但我不知道这是否是完全正确的(德尔福code ..)

函数readPt(INSTR:TStream;电话号码:ANNpoint):布尔;
VAR
  尺寸:Longint型; //字节数来读取
开始
  inStr.Size:=一下SizeOf(ANNcoord)*黯淡;
  结果:= inStr.Read(P ^,大小)=大小;
结束;

下面是我在实施不成功的尝试是,而循环德尔福(无关code省略):

VAR
  dataPts:AnnPointArray;
  BinStream:内存流;
  朦胧,maxPts,NPTS:LongInt的;
开始
  暗淡:= 2;
  maxPts:= 1000;
  dataPts:= annAllocPts(maxPts,DIM);  // GENERATE TStream数据
  ///////////////////////////
  BinStream:= TMemoryStream.Create;
  BinStream.SetSize(1001);
  为NPTS:= 0到1000做
  开始
    BinStream.Write(NPTS,1);
  结束;
  BinStream.Position:= 0
  ///////////////////////////  NPTS:= 0;
  而NPTS< maxPts做
  开始
    readPt(BinStream,dataPts [NPTS]);
    NPTS:= NPTS + 1;
  结束;
结束;

当我尝试运行这一点,我在 readPt获得的分段错误(BinStream,dataPts [NPTS]);

我将非常感激,如果有人花时间帮我在这里!

编辑:案例 annAllocPts() C ++函数是很重要的..这里是:

ANNpointArray annAllocPts(INT N,INT DIM)//分配ñ点在昏暗
{
    ANNpointArray PA =新ANNpoint [N]; //分配点
    ANNpoint P =新ANNcoord [N *黯淡]。 //分配给COORDS空间
    的for(int i = 0; I< N;我++){
        巴[I] =及(ρ[我*暗淡]);
    }
    每年回报;
}

这里是我是如何实现的:

函数annAllocPts(N:Longint型;暗淡:Longint型):ANNpointArray的cdecl;
  外部ANN.dll人指数33;

编辑2:我仍然有麻烦填写正确输入流(我认为)...

VAR
 ThisDouble:双;
开始
  binstream:= TMemoryStream.Create;
  ThisDouble:= 1.001;
  为NPTS:= 0到maxPts *黯淡做
  开始
    binstream.Write(ThisDouble,一下SizeOf(ThisDouble));
  结束;
  BinStream.Position:= 0;  NPTS:= 0;
  而NPTS< maxPts做
  开始
   如果不是readPt(BinStream,dataPts [NPTS]),然后
    打破;
  NPTS:= NPTS + 1;
结束;


解决方案

您code调用DLL函数分配双1000 2元素的数组的数组。然后你填一个流与1001的字节的。你想填充16000字节的存储空间只有1001字节的数据。

此外,你流中把数据不反正形成有意义的双重价值。

此外,的 readPt 的版本是错误的。你分配 inStr.Size ,而不是本地尺寸变量。编译器应该警告你,尺寸未经初始化使用。您的code的输入流截断为一个阵列段的长度,然后尝试读取未知数量从流字节的效果。使用<一个href=\"http://stackoverflow.com/questions/7086417/conversion-from-c-to-delphi-simple/7086669#7086669\">the版本从您的其他问题了。

I am trying to use the ANN (approximate nearest neighbor) library (the .dll) within my Delphi code. The library is written in C++, and although the data types are fairly simple I am having some trouble.

I used h2pas to convert the C++ header file as far as I could get it. I ended up with the following data types (C++ on the left, Delphi on the right):

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;

For starters I want to sucessfully port the sample included with the ANN library. The C++ code for this sample is linked here without comments (if you want the comments, just download the library from ANN's webpage).

Even more specifically, here is the excerpt that I am having trouble with (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;
}

A member on stackoverflow helped me with a partial conversion of the readPt function - but I am not sure if it is completely correct (Delphi code..):

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; 

Here is my unsuccessful attempt at implementing that while loop in Delphi (irrelevant code omitted):

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;   

When I attempt to run this I get a segmentation fault at readPt(BinStream, dataPts[nPts]);

I will be extremely grateful if someone would take the time to help me out here!

Edit: In case the C++ function for annAllocPts() is important.. here it is:

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;
}

And here is how I implemented it:

function annAllocPts(n: longint; dim: longint): ANNpointArray cdecl;
  external 'ANN.dll' index 33;     

Edit 2: I am still having trouble properly filling the input stream (I think)...

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;                    

解决方案

Your code calls the DLL function to allocate a array of 1000 2-element arrays of Double. Then you fill a stream with 1001 bytes. You're trying to populate 16000 bytes of storage with only 1001 bytes of data.

Furthermore, the data you're putting in the stream doesn't form meaningful Double values anyway.

Also, your version of readPt is wrong. You're assigning inStr.Size instead of the local Size variable. The compiler should have warned you that Size was used without being initialized. Your code has the effect to truncating the input stream to the length of one array segment and then attempting to read an unknown number of bytes from the stream. Use the version you got from your other question.

这篇关于从C指针和数组的转换++德尔福的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆