SDK 指针的问题 - c++ 到 Delphi 的翻译
Posted
技术标签:
【中文标题】SDK 指针的问题 - c++ 到 Delphi 的翻译【英文标题】:Problem with SDK pointers - c++ to Delphi translating 【发布时间】:2019-01-16 14:44:27 【问题描述】:我正在努力使用 HikVision SDK,试图让它在 Delphi 中工作。 C++ 中有一些示例,但我在翻译到 Delphi 时遇到了指针问题。直到那一刻代码似乎有效,因为我得到了正确的车牌号。 这是正确的等价物:BYTE *pBuffer -> PByte 吗? 如何从pBuffer中提取图片?
C++ 代码:
typedef struct tagNET_ITS_PICTURE_INFO
DWORD dwDataLen; //Media data length
BYTE byType;
BYTE byAbsTime[32];
NET_VCA_RECT struPlateRect;
BYTE *pBuffer; //Data pointer
DWORD dwUTCTime;
//...
NET_ITS_PICTURE_INFO, *LPNET_ITS_PICTURE_INFO;
typedef struct tagNET_ITS_PLATE_RESULT
//...
NET_DVR_PLATE_INFO struPlateInfo;
NET_ITS_PICTURE_INFO struPicInfo[6];
NET_ITS_PLATE_RESULT, *LPNET_ITS_PLATE_RESULT;
void CALLBACK MSesGCallback(LONG lCommand, NET_DVR_ALARMER *pAlarmer, char *pAlarmInfo, DWORD dwBufLen, void* pUser)
char filename[100];
FILE *fSnapPic = NULL;
switch (lCommand)
case COMM_ITS_PLATE_RESULT:
NET_ITS_PLATE_RESULT struITSPlateResult = 0 ;
memcpy(&struITSPlateResult, pAlarmInfo, sizeof(struITSPlateResult));
printf("Plate: %s\n", struITSPlateResult.struPlateInfo.sLicense);
if (struITSPlateResult.struPicInfo[0].dwDataLen != 0)
sprintf(filename, "./pic/%d.jpg", 0);
fSnapPic = fopen(filename, "wb");
fwrite(struITSPlateResult.struPicInfo[0].pBuffer, struITSPlateResult.struPicInfo[0].dwDataLen, 1, fSnapPic);
fclose(fSnapPic);
return;
德尔福代码:
LPNET_ITS_PICTURE_INFO = ^NET_ITS_PICTURE_INFO;
NET_ITS_PICTURE_INFO = record
dwDataLen: DWORD;
byType: BYTE;
byAbsTime: array [0..31] of BYTE;
struPlateRect: NET_VCA_RECT;
pBuffer: PByte; // ????????
dwUTCTime: DWORD;
//(...)
end;
LPNET_ITS_PLATE_RESULT = ^NET_ITS_PLATE_RESULT;
NET_ITS_PLATE_RESULT = record
//(...)
struPlateInfo: NET_DVR_PLATE_INFO;
struPicInfo: Array [0..5] of NET_ITS_PICTURE_INFO;
end;
procedure MessageCallBack(lCommand:longint; pAlarmer:LPNET_DVR_ALARMER; pAlarmInfo:PAnsiChar; dwBufLen:LongInt; pUser:pointer); stdcall;
var
struAlarmInfo: LPNET_DVR_ALARMINFO_V30;
struPlateResult: LPNET_ITS_PLATE_RESULT;
begin
case lCommand of
COMM_ITS_PLATE_RESULT:
begin
New(struPlateResult);
FillChar(struPlateResult^, SizeOf(NET_ITS_PLATE_RESULT), 0);
Move(pAlarmInfo^, struPlateResult^, Sizeof(NET_ITS_PLATE_RESULT));
Form1.memoOut.Lines.Add('sLicense: ' + struPlateResult.struPlateInfo.sLicense);
if (struPlateResult.struPicInfo[0].dwDataLen >0) then
??? how to get the picture from struPlateResult.struPicInfo[0].pBuffer ?
end;
end;
end;
问候
【问题讨论】:
见:***.com/questions/100596/… 不要使用New
。如果需要分配记录,请使用局部变量。如果您需要指向该记录的指针,请使用@
获取其地址。必须管理堆分配以在堆栈上使用自动分配更为复杂。正如您的代码泄漏该分配所见证的那样。
其实你不需要复制记录。您可以投射指针。 C++ 代码在这方面也很浪费。
如果你的意思是 struPlateResult := LPNET_ITS_PLATE_RESULT(pAlarmInfo);
而不是 New/FillChar/Move
那么它也可以 :)
【参考方案1】:
是的,PByte
或 PByteArray
是正确的翻译。
如果缓冲区包含有效的文件内容,您可以将其保存到文件中:
FS := TFileStream.Create('test.jpg', fmCreate);
try
FS.Write(struITSPlateResult.struPicInfo[0].pBuffer^,
struITSPlateResult.struPicInfo[0].dwDataLen);
finally
FS.Free;
end;
【讨论】:
以上是关于SDK 指针的问题 - c++ 到 Delphi 的翻译的主要内容,如果未能解决你的问题,请参考以下文章
(转)Delphi2009初体验 - 语言篇 - 智能指针(Smart Pointer)的实现