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】:

是的,PBytePByteArray 是正确的翻译。

如果缓冲区包含有效的文件内容,您可以将其保存到文件中:

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)的实现

将 Delphi 逐步移植到 C++

Delphi 如何判断鼠标指针是不是在窗口中

嵌入式开发——用C语言调用C++的动态库时函数指针为空

Delphi XE8如何同Eclipse使用相同的Android SDK?

Delphi2007升级到Delphi 2010总结