Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ CPP到Delphi的转换_C++_Delphi_Dll - Fatal编程技术网

C++ CPP到Delphi的转换

C++ CPP到Delphi的转换,c++,delphi,dll,C++,Delphi,Dll,** 解决 ** 感谢Rob帮我解决了问题 在组件单元fDict上创建全局var 实施三种方法,一种添加,一种删除,一种检索; 使主类创建、清除和销毁全局变量以避免内存泄漏 使TDispositivo的连接功能为fDict供电 进行回调以重试并继续。 使用TDispositivo的断开功能删除fDict中的参考,并保持其更新 ** 编辑 ** 我发现了崩溃错误,我正在组件类中实现dll,并尝试使用 TSnapRev=对象stdcall的过程(XXXXX) 。。。 私有的 程序回调快照(XXXXX

**

解决

**

感谢Rob帮我解决了问题

在组件单元fDict上创建全局var 实施三种方法,一种添加,一种删除,一种检索; 使主类创建、清除和销毁全局变量以避免内存泄漏 使TDispositivo的连接功能为fDict供电 进行回调以重试并继续。 使用TDispositivo的断开功能删除fDict中的参考,并保持其更新

**

编辑

**

我发现了崩溃错误,我正在组件类中实现dll,并尝试使用

TSnapRev=对象stdcall的过程(XXXXX)

。。。 私有的 程序回调快照(XXXXX);stdcall;

客户端_SetSnapRevCallBack(callbackSnapshot,FSDKUSer)

callbacksnapshot已触发,但在触发后引发访问冲突

O意识到返回变量的顺序总是放错位置,然后我改变了方法,将callbacksnapshot过程移出类,并改变类型声明,如下所示:

类型 TSnapRev=程序(XXXXX);stdcall

TDispositivo=类 私有的 结束

程序回调快照(XXXXX);stdcall

。。。 CLIENT_SetSnapRevCallBack(@callbackSnapshot,FSDKUSer);

现在回调触发了,变量的顺序正确,之后没有访问冲突,但是,我需要从我的TDispositivo实例或TDispositivo实例的所有者调用一些函数(事件等),在一个外部过程中我不能

我怎样才能在课堂上做到这一点

我曾尝试声明一个变量FSDKSnap:TRevSap(当TRevSap是一种对象类型时),但得到了相同的错误或miplaced vars以及访问冲突

**

原创的

**

继续进行我的大华dll到Delphi的转换。现在我被困在回调中,实际上是在所用类型的定义中

标题中有cpp代码

    #define BYTE        unsigned char
    #define UINT        unsigned int

    // Snapshot parameter structure 
    typedef struct _snap_param
    {
        unsigned int        Channel;                // Snapshot channel
        unsigned int        Quality;                // Image quality:level 1 to level 6
        unsigned int        ImageSize;              // Video size;0:QCIF,1:CIF,2:D1
        unsigned int        mode;                   // Snapshot mode;0:request one frame,1:send out requestion regularly,2: Request consecutively
        unsigned int        InterSnap;              // Time unit is second.If mode=1, it means send out requestion regularly. The time is valid.
        unsigned int        CmdSerial;              // Request serial number
        unsigned int        Reserved[4];
    } SNAP_PARAMS, *LPSNAP_PARAMS;

    // Snapshot callback function original shape 
    // Encode Type 10: jpeg 0: number i frame of mpeg4 
    typedef void (CALLBACK *fSnapRev)(LLONG lLoginID, BYTE *pBuf, UINT RevLen, UINT EncodeType, DWORD CmdSerial, LDWORD dwUser);

    // Set snapshot callback function 
    CLIENT_NET_API void CALL_METHOD CLIENT_SetSnapRevCallBack(fSnapRev OnSnapRevMessage, LDWORD dwUser);    

    // Snapshot request
    CLIENT_NET_API BOOL CALL_METHOD CLIENT_SnapPicture(LLONG lLoginID, SNAP_PARAMS par);
查看cpp代码,它将BYTE定义为无符号字符,因此映射到Delphi(BYTE),UINT映射到Cardinal

该结构也被映射到Cardinal

--->第一个问题

回调fSnapRev有(BYTE*pBuf),所以我想是一个指向BYTE(Delphi PByte)的指针,我怀疑这就是问题所在。内存太少的缓冲区是不正确的,可能是字节数组或pansichar数组。我怎么知道?像尝试和错过?我接受建议

RevLen和Encode类型映射到Cardinal

这是演示应用程序中的cpp代码

  //First part of the method to initialize the dll, 

    BOOL ret = CLIENT_Init(DisConnectFunc, (LDWORD)this);
    if (ret)
    {
        CLIENT_SetSnapRevCallBack(SnapPicRet,(LDWORD)this);
        //here defining the callback
        CLIENT_SetAutoReconnect(ReConnectFunc, (LDWORD)this);
    }
    else
    {
        MessageBox(ConvertString("initialize SDK failed!"), ConvertString("prompt"));
    }

    //the callback
    void CALLBACK SnapPicRet(LLONG ILoginID, BYTE *pBuf, UINT RevLen, UINT EncodeType, DWORD CmdSerial, 
    LDWORD dwUser)
    {
        CCapturePictureDlg *pThis = (CCapturePictureDlg*)dwUser;
        pThis->OnOnePicture(ILoginID,pBuf,RevLen,EncodeType,CmdSerial);
    }

    
    void CCapturePictureDlg::OnOnePicture(LLONG ILoginID, BYTE *pBuf, UINT RevLen, UINT EncodeType, UINT 
CmdSerial)
    {
        //Get file path
        char path[1000];
        int filelen = GetModuleFileName(NULL,path,1000);
        int i = filelen;
        while(path[i]!='\\')
        {
            i--;
        }
        path[i + 1] = '\0';
    
        //Get file name
        CString filepath(path);
        CString filename = "mpeg4.JPG";
        CString strfile = filepath + filename;
        char *pFileName = strfile.GetBuffer(200);
  
        /* Save image original file */
        FILE *stream;        
        if( (stream = fopen((const char*) pFileName, "wb")) != NULL )
        {
            int numwritten = fwrite( pBuf, sizeof( char ), RevLen, stream );
            fclose( stream );
        }
        
        /*Veirfy image encode type. If it is an I frame of mpeg4,then call I frame to decode to BMP to display.*/
        if ( EncodeType == 0) 
        {
            //int iRet = IFrameToBmp("tmp.bmp",pFileName);
            //if (iRet == 1)
            //{
            //  ShowBitmap("tmp.bmp");
            //}
        }
        else if (EncodeType == 10)
        {
            //ShowBitmap(pFileName);
            ShowSnapImage(pFileName);
        }
    }

在OnOnePicture中,第一个代码是定义要存储的图像文件的路径,然后在文件流中写入缓冲区。如果缓冲区和大小来自pBuf和RevLen,那么我可以将其写入TMemoryStream并分配给TJpegImage,但仍然不知道pBuf到底是什么

另一个ocuard内容是数据,revLen返回值10,太小,无法作为图像的字节长度

我的Delphi代码

  TSnapRev = procedure(lLoginID: Integer; pBuf: PByte; RevLen: Cardinal; EncodeType: Cardinal; CmdSerial: DWORD; dwUser: DWORD) of object stdcall;

// Snapshot parameter structure
  PSnapParams = ^TSnapParams;
  TSnapParams = record
    Channel: Cardinal;               // Snapshot channel
    Quality: Cardinal;               // Image quality:level 1 to level 6
    ImageSize: Cardinal;             // Video size;0:QCIF,1:CIF,2:D1
    mode: Cardinal;                  // Snapshot mode;0:request one frame,1:send out requestion regularly,2: Request consecutively
    InterSnap: Cardinal;             // Time unit is second.If mode=1, it means send out requestion regularly. The time is valid.
    CmdSerial: Cardinal;             // Request serial number
    Reserved: array[0..3] of Cardinal;
  end;

// Snapshot request
  function CLIENT_SnapPicture(lLoginID: Integer; par: TSnapParams): Boolean;  stdcall; external 'dhnetsdk.dll';

  procedure callbackSnapshot(lLoginID: Integer; pBuf: PByte; RevLen: Cardinal; EncodeType: Cardinal; CmdSerial: DWORD; dwUser: DWORD); stdcall;

 //Part of my initDll function
   FInicializado := CLIENT_Init(callbackDis,FSDKUser);
  if FInicializado then
    begin
      CLIENT_SetSnapRevCallBack(callbackSnapshot,FSDKUSer);
    end;
   Result := FInicializado;

  //Snapshot wrapper procedure
  procedure TDispositivo.SDKSnapshot;
  var
    sIn: TSnapParams;
  begin
    ZeroMemory(@sIn, SizeOf(sIn));
    With sIn do
      begin
        Channel := 1;
        mode := 0;
        CmdSerial := 0;
        if not CLIENT_SnapPicture(FLoginHandler,sIn) then
          begin
            doErro(999,'Não foi possível tirar o snapshot');
          end;
      end;
  end; 

//the callback implementation
procedure TDispositivo.callbackSnapshot(lLoginID: Integer; pBuf: PByte; RevLen: Cardinal; EncodeType: Cardinal; CmdSerial: DWORD; dwUser: DWORD);
var
  F: TMemoryStream;
  jpg : TJpegImage;
begin
  Showmessage('Tamanho do buffer: ' + SizeOf(pBuf).ToString + #13 +
              'RevLen: ' + RevLen.ToString + #13 +
              'Tipo: ' + EncodeType.ToString + #13 +
              'CmdSerial: ' + CmdSerial.ToString
              );
  F := TMemoryStream.Create;
  jpg := TJPEGImage.Create;
  Try
    F.Write(pBuf,RevLen);
    //F.Write(pBuf^,RevLen);
    F.Position:= 0;
    jpg.LoadFromStream(F);
    fOwner.doSnapshot(self,jpg);
  Finally
    FreeAndNil(F);
    FreeAndNil(jpg);
  End;
end;  

当我调用SDKSnapshot时,我得到了放置在callbackfunction中的“showmessage”值,但在im调试模式下,我得到了无限访问冲突,在发布模式下,应用程序在showmessage之后关闭

我尝试在回调时不做任何事情,但仍然会遇到访问冲突和终止


我想知道我的问题是否在于回调过程pBuf的声明。

我怀疑您的LLoginId应该是Int64。。LLON将在源平台的编译器方言/系统包含中定义。(见:)

您的错误表明这些参数包含垃圾(见下文),如果它们的顺序不正确,就会发生这种情况-这可能意味着您的参数大小错误(因此LLoginId没有从堆栈读取所有值,它后面的所有变量都将损坏)

您可以尝试制作LLogin Int64,或者如果您想进一步研究,可以尝试以下方法:

您似乎成功地调用了回调例程,但例程中接收到的变量不正确。(您说您只有revLen 10,访问冲突错误表明pBuf可能指向垃圾)

您已经将例程声明为stdcall,这应该是正确的,参数将按照正常的“C”约定在堆栈上传递

如果中断例程的条目并在CPU视图中查看,您应该看到变量是从堆栈中读取的,并确定每个变量都设置正确。您应该能够将pBuf的地址放入内存窗口,并确定它是否指向JPEG ssignature中的JPEG数据


您还可以查看堆栈的内存转储,检查已传递给您的内容,并查看是否可以确定所需变量的实际位置。

我怀疑您的LLoginId应该是Int64。。LLON将在源平台的编译器方言/系统包含中定义。(见:)

您的错误表明这些参数包含垃圾(见下文),如果它们的顺序不正确,就会发生这种情况-这可能意味着您的参数大小错误(因此LLoginId没有从堆栈读取所有值,它后面的所有变量都将损坏)

您可以尝试制作LLogin Int64,或者如果您想进一步研究,可以尝试以下方法:

您似乎成功地调用了回调例程,但例程中接收到的变量不正确。(您说您只有revLen 10,访问冲突错误表明pBuf可能指向垃圾)

您已经将例程声明为stdcall,这应该是正确的,参数将按照正常的“C”约定在堆栈上传递

如果中断例程的条目并在CPU视图中查看,您应该会看到变量是从堆栈中读取的,并且