指针和数组从c++到Delphi的转换
Conversion of pointers and arrays from C++ to Delphi
我试图在我的Delphi代码中使用ANN
(近似近邻)库(.dll)。该库是用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++代码…):
...
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;
这是我在Delphi中实现while
循环的不成功尝试(省略了无关的代码):
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]);
编辑:如果annAllocPts()
的c++函数很重要…
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;
您的代码调用DLL函数来分配1000个双元素数组。然后用1001 字节填充流。您试图用1001字节的数据填充16000字节的存储空间。
此外,你放入流中的数据不会形成有意义的Double值。
还有,你的版本的readPt
是错误的。您正在分配inStr.Size
而不是本地Size
变量。编译器应该警告您没有初始化就使用了Size
。您的代码会将输入流截断为一个数组段的长度,然后尝试从流中读取未知数量的字节。使用你从另一个问题中得到的版本
readPt()中的代码是正确的。但是它一次读取多个double,就像另一个问题中的c++示例一样。
你的问题是,你写maxPts(=1000)双精度到内存流,但然后,在一个循环(maxPts =1000迭代),你读dim(= 2)双精度每次迭代(readPt读取dim anncoord在一次),所以你尝试读1000*2 anncoord和耗尽数据之前,你到达结束。您应该检查readPt()在循环中的返回值,如果返回值为false则中断:
nPts:=0;
while nPts < maxPts do
begin
if not readPt(BinStream, dataPts[nPts]) then
Break;
nPts:=nPts+1;
end;
当然,也可以将dim * maxPts项写入内存流。
- 将 Delphi 的字符串转换为 std::字符串用于C++
- 如何将C/C 回调函数转换为Delphi
- 将C 回调功能转换为Delphi
- 如何将C 代码转换为Delphi
- 将数组指针访问从C++转换为Delphi
- 从C++到Delphi的类型转换
- Delphi中的类型转换指针添加
- 将 C 中的按位语句转换为 Delphi
- 使用消息处理程序将 c++ dll 调用转换为 delphi
- Delphi - 从 dll 调用转换(读取)C++ NULL 终止数组
- 将 Direct3D C++ 函数转换为 Delphi
- 如何将MQL4代码转换为C++/Delphi DLL(Forex Tester API)
- Delphi在将VirtualProtect EAT钩子例程从C转换为Delphi时出现问题
- 更正从C++到delphi AnsiString的字节转换
- 代码从C/C++转换为Delphi
- 将C++内联汇编函数转换为delphi内联汇编函数
- c++到Delphi的指针转换
- 可以将带有类的c++头文件转换为Delphi单元吗?
- 将C头中的__declspec转换为Delphi
- 如何将c++头文件转换为delphi