0) { 如果(!PlayM4_设置流模式(lPort,Stream_REALTIME)) { 打破 } 如果(!PlayM4_OpenStream(lPort、pBuffer、dwBufSize、1024*1024)) { 打破 } 如果(!PlayM4_Play(lPort,hWnd))//开始播放 { 打破 } } 案例网络\u DVR\u STREAMDATA://流数据 如果(dwBufSize>0&&lPort!=-1) { 如果(!PlayM4_InputData(lPort、pBuffer、dwBufSize)) { 打破 } } } } int _tmain(int argc,_TCHAR*argv[] { NET_DVR_Init(); 网络DVR设备信息V30结构设备信息; lUserID=NET\u DVR\u Login\u V30(“193.160.101.1”、8000、“admin”、“12345”和struDeviceInfo); if(lUserID0,则 开始 如果不是(播放M4_设置流模式(lPort,Stream_REALTIME)),则 开始 出口 终止 如果不是(PlayM4_OpenStream(lPort、pBuffer、dwBufSize、1024*1024)),则 开始 出口 终止 如果不是(播放M4\u播放(lPort,hPlayWnd)),则 开始 出口 终止 如果dwDataType=NET\u DVR\u STREAMDATA,则 开始 如果(dwBufSize>0)和(lPort-1),则 开始 如果不是(PlayM4_输入数据(lPort、pBuffer、dwBufSize)),则 开始 出口 终止 终止 终止 终止 终止 终止 程序TForm1.btnPlayClickClick(发送方:TObject); 变量 lRealPlayHandle:长柄; 开始 lRealPlayHandle:=NET\u DVR\u RealPlay\u V40(iLoginID,struPlayInfo,MyRealDataCallBack\u V30,null); 终止 函数NET\u DVR\u RealPlay\u V40(lUserID:LongInt;var lpPreviewInfo:TNET\u DVR\u PREVIEWINFO;RealDataCallBack\u V30:fRealDataCallBack\u V30;pUser:Pointer):LongInt;stdcall;外部'HCNetSDK.dll'名称'NET_DVR_RealPlay_V40';,c++,delphi,C++,Delphi" /> 0) { 如果(!PlayM4_设置流模式(lPort,Stream_REALTIME)) { 打破 } 如果(!PlayM4_OpenStream(lPort、pBuffer、dwBufSize、1024*1024)) { 打破 } 如果(!PlayM4_Play(lPort,hWnd))//开始播放 { 打破 } } 案例网络\u DVR\u STREAMDATA://流数据 如果(dwBufSize>0&&lPort!=-1) { 如果(!PlayM4_InputData(lPort、pBuffer、dwBufSize)) { 打破 } } } } int _tmain(int argc,_TCHAR*argv[] { NET_DVR_Init(); 网络DVR设备信息V30结构设备信息; lUserID=NET\u DVR\u Login\u V30(“193.160.101.1”、8000、“admin”、“12345”和struDeviceInfo); if(lUserID0,则 开始 如果不是(播放M4_设置流模式(lPort,Stream_REALTIME)),则 开始 出口 终止 如果不是(PlayM4_OpenStream(lPort、pBuffer、dwBufSize、1024*1024)),则 开始 出口 终止 如果不是(播放M4\u播放(lPort,hPlayWnd)),则 开始 出口 终止 如果dwDataType=NET\u DVR\u STREAMDATA,则 开始 如果(dwBufSize>0)和(lPort-1),则 开始 如果不是(PlayM4_输入数据(lPort、pBuffer、dwBufSize)),则 开始 出口 终止 终止 终止 终止 终止 终止 程序TForm1.btnPlayClickClick(发送方:TObject); 变量 lRealPlayHandle:长柄; 开始 lRealPlayHandle:=NET\u DVR\u RealPlay\u V40(iLoginID,struPlayInfo,MyRealDataCallBack\u V30,null); 终止 函数NET\u DVR\u RealPlay\u V40(lUserID:LongInt;var lpPreviewInfo:TNET\u DVR\u PREVIEWINFO;RealDataCallBack\u V30:fRealDataCallBack\u V30;pUser:Pointer):LongInt;stdcall;外部'HCNetSDK.dll'名称'NET_DVR_RealPlay_V40';,c++,delphi,C++,Delphi" />

Delphi如何在另一个函数中使用回调函数作为参数? < >我想把C++代码转换成Delphi。C++代码从相机(海康威视)中获取数据流。这是我想转换成Delphi的C++代码:< /P> void CALLBACK fRealDataCallBack(LONG lRealHandle, DWORD dwDataType, BYTE *pBuffer, DWORD dwBufSize, void* dwUser) { HWND hWnd = GetConsoleWindow(); switch (dwDataType) { case NET_DVR_SYSHEAD: //System head if (!PlayM4_GetPort(&lPort)) //Get unused port { break; } if (dwBufSize > 0) { if (!PlayM4_SetStreamOpenMode(lPort, STREAME_REALTIME)) { break; } if (!PlayM4_OpenStream(lPort, pBuffer, dwBufSize, 1024 * 1024)) { break; } if (!PlayM4_Play(lPort, hWnd)) //Start play { break; } } case NET_DVR_STREAMDATA: //Stream data if (dwBufSize > 0 && lPort != -1) { if (!PlayM4_InputData(lPort, pBuffer, dwBufSize)) { break; } } } } int _tmain(int argc, _TCHAR* argv[]) { NET_DVR_Init(); NET_DVR_DEVICEINFO_V30 struDeviceInfo; lUserID = NET_DVR_Login_V30("193.160.101.1", 8000, "admin", "12345", &struDeviceInfo); if (lUserID < 0) { printf("Login error, %d\n", NET_DVR_GetLastError()); NET_DVR_Cleanup(); return 0; } LONG lRealPlayHandle; NET_DVR_PREVIEWINFO struPlayInfo = { 0 }; struPlayInfo.hPlayWnd = NULL; //If need to decode, please set it valid. If want to get stream data only, it can be set to NULL struPlayInfo.lChannel = 1; //Preview channel NO. //struPlayInfo.dwStreamType = 0; //0-main stream, 1-sub stream, 2-stream3, 3-stream4. struPlayInfo.dwLinkMode = 0; //0-TCP mode, 1-UDP mode, 2-Multi-play mode, 3-RTP mode, 4-RTP/RTSP, 5-RTSP/HTTP lRealPlayHandle = NET_DVR_RealPlay_V40(lUserID, &struPlayInfo, fRealDataCallBack, NULL) return 0; } void CALLBACK fRealDataCallBack(长lRealHandle、DWORD DWDATATATYPE、BYTE*pBuffer、DWORD dwBufSize、void*dwUser) { HWND HWND=GetConsoleWindow(); 开关(dwDataType) { 案例网络\u DVR\u系统头://系统头 如果(!PlayM4_GetPort(&lPort))//获取未使用的端口 { 打破 } 如果(dwBufSize>0) { 如果(!PlayM4_设置流模式(lPort,Stream_REALTIME)) { 打破 } 如果(!PlayM4_OpenStream(lPort、pBuffer、dwBufSize、1024*1024)) { 打破 } 如果(!PlayM4_Play(lPort,hWnd))//开始播放 { 打破 } } 案例网络\u DVR\u STREAMDATA://流数据 如果(dwBufSize>0&&lPort!=-1) { 如果(!PlayM4_InputData(lPort、pBuffer、dwBufSize)) { 打破 } } } } int _tmain(int argc,_TCHAR*argv[] { NET_DVR_Init(); 网络DVR设备信息V30结构设备信息; lUserID=NET\u DVR\u Login\u V30(“193.160.101.1”、8000、“admin”、“12345”和struDeviceInfo); if(lUserID0,则 开始 如果不是(播放M4_设置流模式(lPort,Stream_REALTIME)),则 开始 出口 终止 如果不是(PlayM4_OpenStream(lPort、pBuffer、dwBufSize、1024*1024)),则 开始 出口 终止 如果不是(播放M4\u播放(lPort,hPlayWnd)),则 开始 出口 终止 如果dwDataType=NET\u DVR\u STREAMDATA,则 开始 如果(dwBufSize>0)和(lPort-1),则 开始 如果不是(PlayM4_输入数据(lPort、pBuffer、dwBufSize)),则 开始 出口 终止 终止 终止 终止 终止 终止 程序TForm1.btnPlayClickClick(发送方:TObject); 变量 lRealPlayHandle:长柄; 开始 lRealPlayHandle:=NET\u DVR\u RealPlay\u V40(iLoginID,struPlayInfo,MyRealDataCallBack\u V30,null); 终止 函数NET\u DVR\u RealPlay\u V40(lUserID:LongInt;var lpPreviewInfo:TNET\u DVR\u PREVIEWINFO;RealDataCallBack\u V30:fRealDataCallBack\u V30;pUser:Pointer):LongInt;stdcall;外部'HCNetSDK.dll'名称'NET_DVR_RealPlay_V40';

Delphi如何在另一个函数中使用回调函数作为参数? < >我想把C++代码转换成Delphi。C++代码从相机(海康威视)中获取数据流。这是我想转换成Delphi的C++代码:< /P> void CALLBACK fRealDataCallBack(LONG lRealHandle, DWORD dwDataType, BYTE *pBuffer, DWORD dwBufSize, void* dwUser) { HWND hWnd = GetConsoleWindow(); switch (dwDataType) { case NET_DVR_SYSHEAD: //System head if (!PlayM4_GetPort(&lPort)) //Get unused port { break; } if (dwBufSize > 0) { if (!PlayM4_SetStreamOpenMode(lPort, STREAME_REALTIME)) { break; } if (!PlayM4_OpenStream(lPort, pBuffer, dwBufSize, 1024 * 1024)) { break; } if (!PlayM4_Play(lPort, hWnd)) //Start play { break; } } case NET_DVR_STREAMDATA: //Stream data if (dwBufSize > 0 && lPort != -1) { if (!PlayM4_InputData(lPort, pBuffer, dwBufSize)) { break; } } } } int _tmain(int argc, _TCHAR* argv[]) { NET_DVR_Init(); NET_DVR_DEVICEINFO_V30 struDeviceInfo; lUserID = NET_DVR_Login_V30("193.160.101.1", 8000, "admin", "12345", &struDeviceInfo); if (lUserID < 0) { printf("Login error, %d\n", NET_DVR_GetLastError()); NET_DVR_Cleanup(); return 0; } LONG lRealPlayHandle; NET_DVR_PREVIEWINFO struPlayInfo = { 0 }; struPlayInfo.hPlayWnd = NULL; //If need to decode, please set it valid. If want to get stream data only, it can be set to NULL struPlayInfo.lChannel = 1; //Preview channel NO. //struPlayInfo.dwStreamType = 0; //0-main stream, 1-sub stream, 2-stream3, 3-stream4. struPlayInfo.dwLinkMode = 0; //0-TCP mode, 1-UDP mode, 2-Multi-play mode, 3-RTP mode, 4-RTP/RTSP, 5-RTSP/HTTP lRealPlayHandle = NET_DVR_RealPlay_V40(lUserID, &struPlayInfo, fRealDataCallBack, NULL) return 0; } void CALLBACK fRealDataCallBack(长lRealHandle、DWORD DWDATATATYPE、BYTE*pBuffer、DWORD dwBufSize、void*dwUser) { HWND HWND=GetConsoleWindow(); 开关(dwDataType) { 案例网络\u DVR\u系统头://系统头 如果(!PlayM4_GetPort(&lPort))//获取未使用的端口 { 打破 } 如果(dwBufSize>0) { 如果(!PlayM4_设置流模式(lPort,Stream_REALTIME)) { 打破 } 如果(!PlayM4_OpenStream(lPort、pBuffer、dwBufSize、1024*1024)) { 打破 } 如果(!PlayM4_Play(lPort,hWnd))//开始播放 { 打破 } } 案例网络\u DVR\u STREAMDATA://流数据 如果(dwBufSize>0&&lPort!=-1) { 如果(!PlayM4_InputData(lPort、pBuffer、dwBufSize)) { 打破 } } } } int _tmain(int argc,_TCHAR*argv[] { NET_DVR_Init(); 网络DVR设备信息V30结构设备信息; lUserID=NET\u DVR\u Login\u V30(“193.160.101.1”、8000、“admin”、“12345”和struDeviceInfo); if(lUserID0,则 开始 如果不是(播放M4_设置流模式(lPort,Stream_REALTIME)),则 开始 出口 终止 如果不是(PlayM4_OpenStream(lPort、pBuffer、dwBufSize、1024*1024)),则 开始 出口 终止 如果不是(播放M4\u播放(lPort,hPlayWnd)),则 开始 出口 终止 如果dwDataType=NET\u DVR\u STREAMDATA,则 开始 如果(dwBufSize>0)和(lPort-1),则 开始 如果不是(PlayM4_输入数据(lPort、pBuffer、dwBufSize)),则 开始 出口 终止 终止 终止 终止 终止 终止 程序TForm1.btnPlayClickClick(发送方:TObject); 变量 lRealPlayHandle:长柄; 开始 lRealPlayHandle:=NET\u DVR\u RealPlay\u V40(iLoginID,struPlayInfo,MyRealDataCallBack\u V30,null); 终止 函数NET\u DVR\u RealPlay\u V40(lUserID:LongInt;var lpPreviewInfo:TNET\u DVR\u PREVIEWINFO;RealDataCallBack\u V30:fRealDataCallBack\u V30;pUser:Pointer):LongInt;stdcall;外部'HCNetSDK.dll'名称'NET_DVR_RealPlay_V40';,c++,delphi,C++,Delphi,这是我的Delphi代码 procedure TForm1.MyRealDataCallBack_V30(lRealHandle:Longint;dwDataType:DWORD;pBuffer:PByte;dwBufSize,dwUser:DWORD); stdcall; begin hPlayWnd:=Panel1.Handle; if dwDataType = NET_DVR_SYSHEAD then begin if (

这是我的Delphi代码

 procedure TForm1.MyRealDataCallBack_V30(lRealHandle:Longint;dwDataType:DWORD;pBuffer:PByte;dwBufSize,dwUser:DWORD); stdcall;
    begin

      hPlayWnd:=Panel1.Handle;
      if dwDataType = NET_DVR_SYSHEAD then
       begin
         if (not(PlayM4_GetPort(lPort))) then
         begin
           Exit;
         end;
         if dwBufSize > 0  then
         begin
           if not(PlayM4_SetStreamOpenMode(lPort, STREAME_REALTIME)) then    
           begin
             Exit;
           end;
            if not(PlayM4_OpenStream(lPort, pBuffer, dwBufSize, 1024*1024)) then 
           begin
             Exit;
           end;
             if not(PlayM4_Play(lPort,hPlayWnd)) then
           begin
             Exit;
           end;
           if dwDataType = NET_DVR_STREAMDATA then
            begin
         if (dwBufSize > 0) and (lPort <> -1) then
         begin
           if not(PlayM4_InputData(lPort, pBuffer, dwBufSize)) then
           begin
             Exit
           end;
         end;
       end;
    end;
    end;
    end;
    procedure TForm1.btnPlayClickClick(Sender: TObject);
    var
    lRealPlayHandle :Longint;
    begin
    lRealPlayHandle:=NET_DVR_RealPlay_V40(iLoginID,struPlayInfo,MyRealDataCallBack_V30,null);
    end; 
 function  NET_DVR_RealPlay_V40(lUserID: LongInt;var lpPreviewInfo: TNET_DVR_PREVIEWINFO; RealDataCallBack_V30:fRealDataCallBack_V30;pUser:Pointer): LongInt;stdcall; external 'HCNetSDK.dll' name'NET_DVR_RealPlay_V40';  
procedure TForm1.MyRealDataCallBack_V30(lRealHandle:Longint;dwDataType:DWORD;pBuffer:PByte;dwBufSize,dwUser:DWORD);stdcall;
开始
hPlayWnd:=面板1.手柄;
如果dwDataType=NET\u DVR\u SYSHEAD,则
开始
如果(不是(PlayM4_GetPort(lPort)),则
开始
出口
终止
如果dwBufSize>0,则
开始
如果不是(播放M4_设置流模式(lPort,Stream_REALTIME)),则
开始
出口
终止
如果不是(PlayM4_OpenStream(lPort、pBuffer、dwBufSize、1024*1024)),则
开始
出口
终止
如果不是(播放M4\u播放(lPort,hPlayWnd)),则
开始
出口
终止
如果dwDataType=NET\u DVR\u STREAMDATA,则
开始
如果(dwBufSize>0)和(lPort-1),则
开始
如果不是(PlayM4_输入数据(lPort、pBuffer、dwBufSize)),则
开始
出口
终止
终止
终止
终止
终止
终止
程序TForm1.btnPlayClickClick(发送方:TObject);
变量
lRealPlayHandle:长柄;
开始
lRealPlayHandle:=NET\u DVR\u RealPlay\u V40(iLoginID,struPlayInfo,MyRealDataCallBack\u V30,null);
终止

函数NET\u DVR\u RealPlay\u V40(lUserID:LongInt;var lpPreviewInfo:TNET\u DVR\u PREVIEWINFO;RealDataCallBack\u V30:fRealDataCallBack\u V30;pUser:Pointer):LongInt;stdcall;外部'HCNetSDK.dll'名称'NET_DVR_RealPlay_V40';

我为从海康威视摄像头播放视频定义了回调函数(MyRealDataCallBack),并将此函数用作另一个函数(NET\u DVR\u RealPlay\u V40)中的输入参数。

您不能在此处使用表单方法,您需要常规过程:

 void CALLBACK fRealDataCallBack(LONG lRealHandle, DWORD dwDataType, 
               BYTE *pBuffer, DWORD dwBufSize, void* dwUser)
应该是

procedure fRealDataCallBack(lRealHandle : LongInt; dwDataType: DWORD; 
            pBuffer: PByte; dwBufSize: DWORD; dwUser: Pointer); stdcall;
或者使用静态类过程

type
  TMyClass = class 
....
  class procedure fRealDataCallBack(lRealHandle : LongInt; dwDataType: DWORD; 
            pBuffer: PByte; dwBufSize: DWORD; dwUser: Pointer); stdcall; static;
您的
NET\u DVR\u RealPlay\u V40
是使用类型化回调参数声明的,因此您需要在
NET\u DVR\u RealPlay\u V40
之前声明回调函数的类型:

fRealDataCallBack_V30 = procedure (lRealHandle : LongInt; dwDataType: DWORD; 
            pBuffer: PByte; dwBufSize: DWORD; dwUser: Pointer); stdcall;

您不能在此处使用form方法,您需要常规程序:

 void CALLBACK fRealDataCallBack(LONG lRealHandle, DWORD dwDataType, 
               BYTE *pBuffer, DWORD dwBufSize, void* dwUser)
应该是

procedure fRealDataCallBack(lRealHandle : LongInt; dwDataType: DWORD; 
            pBuffer: PByte; dwBufSize: DWORD; dwUser: Pointer); stdcall;
或者使用静态类过程

type
  TMyClass = class 
....
  class procedure fRealDataCallBack(lRealHandle : LongInt; dwDataType: DWORD; 
            pBuffer: PByte; dwBufSize: DWORD; dwUser: Pointer); stdcall; static;
您的
NET\u DVR\u RealPlay\u V40
是使用类型化回调参数声明的,因此您需要在
NET\u DVR\u RealPlay\u V40
之前声明回调函数的类型:

fRealDataCallBack_V30 = procedure (lRealHandle : LongInt; dwDataType: DWORD; 
            pBuffer: PByte; dwBufSize: DWORD; dwUser: Pointer); stdcall;

您正在尝试使用表单类的非静态方法作为回调。非静态方法有一个隐藏的
Self
参数,照相机API将无法填充该参数(除非创建代理存根,这是一种超出本问题范围的高级技术)。您需要从回调中删除该参数,可以将回调声明为独立过程,也可以将其声明为
类static
方法。无论哪种方式,如果需要访问表单对象的成员(如
TPanel
),都可以使用回调的
dwUser
参数将表单的对象指针传递给回调

试着这样做:

interface

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    btnPlay: TButton;
    ...
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure btnPlayClick(Sender: TObject);
    ...
  private
    lRealPlayHandle: LONG;
    lPort: LONG;
    iLoginID: LONG;
    struDeviceInfo: TNET_DVR_DEVICEINFO_V30;
    struPlayInfo: TNET_DVR_PREVIEWINFO;
    ...
    procedure MyRealDataCallBack_V30(lRealHandle: LONG; dwDataType: DWORD; pBuffer: PByte; dwBufSize: DWORD);
    ...
  end;

implementation

function NET_DVR_Init: BOOL; stdcall; external 'HCNetSDK.dll' name 'NET_DVR_Init';  
function NET_DVR_Cleanup: BOOL; external 'HCNetSDK.dll' name 'NET_DVR_Cleanup';  
function NET_DVR_RealPlay_V40(lUserID: LONG; var lpPreviewInfo: TNET_DVR_PREVIEWINFO; RealDataCallBack_V30: fRealDataCallBack_V30; pUser: Pointer): LONG; stdcall; external 'HCNetSDK.dll' name 'NET_DVR_RealPlay_V40';  
// other DVR function declaration as needed...

procedure ActualRealDataCallBack_V30(lRealHandle: LONG; dwDataType: DWORD; pBuffer: PByte; dwBufSize: DWORD; dwUser: Pointer); stdcall;
begin
  TForm1(dwUser).MyRealDataCallBack_V30(lRealHandle, dwDataType, pBuffer, dwBufSize);
end;

procedure TForm1.MyRealDataCallBack_V30(lRealHandle: LONG; dwDataType: DWORD; pBuffer: PByte; dwBufSize: DWORD);
begin
  case dwDataType of
    NET_DVR_SYSHEAD:
    begin
      if not PlayM4_GetPort(lPort) then
        Exit;
      if (dwBufSize > 0) then
      begin
        if not PlayM4_SetStreamOpenMode(lPort, STREAME_REALTIME) then    
          Exit;
        if not PlayM4_OpenStream(lPort, pBuffer, dwBufSize, 1024*1024) then 
          Exit;
        if not PlayM4_Play(lPort, Panel1.Handle) then
          Exit;
      end;
    end;

    NET_DVR_STREAMDATA:
    begin
      if (dwBufSize > 0) and (lPort <> -1) then
      begin
        if not PlayM4_InputData(lPort, pBuffer, dwBufSize) then
          Exit;
      end;
    end;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  err: Integer;
begin
  NET_DVR_Init;

  iLoginID := NET_DVR_Login_V30('193.160.101.1', 8000, 'admin', '12345', struDeviceInfo);
  if (iLoginID < 0) then
  begin
    err := NET_DVR_GetLastError;
    NET_DVR_Cleanup;
    raise Exception.CreateFmt('Login error, %d', [err]);
  end;

  struPlayInfo.hPlayWnd := 0;         //If need to decode, please set it valid. If want to get stream data only, it can be set to NULL
  struPlayInfo.lChannel := 1;       //Preview channel NO.
  //struPlayInfo.dwStreamType := 0;       //0-main stream, 1-sub stream, 2-stream3, 3-stream4.
  struPlayInfo.dwLinkMode := 0;         //0-TCP mode, 1-UDP mode, 2-Multi-play mode, 3-RTP mode, 4-RTP/RTSP, 5-RTSP/HTTP

  lPort := ...;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  NET_DVR_Cleanup;
end;

procedure TForm1.btnPlayClick(Sender: TObject);
begin
  lRealPlayHandle := NET_DVR_RealPlay_V40(iLoginID, struPlayInfo, ActualRealDataCallBack_V30, Self);
end; 

end.
接口
类型
TForm1=类(TForm)
小组1:TPanel;
BTN显示:t按钮;
...
过程表单创建(发送方:ToObject);
销毁程序表(发送方:TObject);
程序btnPlayClick(发件人:ToObject);
...
私有的
lRealPlayHandle:长;
L端口:长;
长的;
StrucDeviceInfo:TNET\u DVR\u DEVICEINFO\u V30;
struPlayInfo:TNET\u DVR\u PREVIEWINFO;
...
过程MyRealDataCallBack_V30(lRealHandle:LONG;dwDataType:DWORD;pBuffer:PByte;dwBufSize:DWORD);
...
终止
实施
函数NET\u DVR\u Init:BOOL;stdcall;外部'HCNetSDK.dll'名称'NET_DVR_Init';
功能网络\u DVR\u清理:BOOL;外部'HCNetSDK.dll'名称'NET_DVR_Cleanup';
功能网络