Мне сложно найти решение для моей проблемы.
Я пытаюсь преобразовать клиентский интерфейс API из С++ в VB.NET, и я думаю, что есть некоторые проблемы с функцией обратного вызова.
части кода С++:
typedef struct {
BYTE m_bRemoteChannel;
BYTE m_bSendMode;
BYTE m_nImgFormat; // =0 cif ; = 1 qcif
char *m_sIPAddress;
char *m_sUserName;
char *m_sUserPassword;
BOOL m_bUserCheck;
HWND m_hShowVideo;
} CLIENT_VIDEOINFO, * PCLIENT_VIDEOINFO;
CPLAYER_API LONG __stdcall MP4_ClientStart (PCLIENT_VIDEOINFO pClientinfo, void (CALLBACK * ReadDataCallBack) (DWORD nPort, UCHAR * pPacketBuffer, DWORD nPacketSize));
void CALLBACK ReadDataCallBack (DWORD nPort, UCHAR * pPacketBuffer, DWORD nPacketSize)
{ TRACE ( "% d\п", nPacketSize); }
.....
aa5.m_sUserName = "123";
aa5.m_sUserPassword="w";
aa5.m_bUserCheck = TRUE;
MP4_ClientSetTTL(64);
nn1 = MP4_ClientStart(&aa5,ReadDataCallBack);
if (nn1 == -1)
{
MessageBox("error");
return;
}
Описание SDK:
Эта функция запускает соединение. Формат вызова:
LONG __stdcall MP4_ClientStart (PCLIENT_VIDEOINFO pClientinfo, void (* ReadDataCallBack) (DWORD nChannel, UCHAR * pPacketBuffer, DWORD nPacketSize))
Параметры pClientinfo содержит информацию. этого соединения.
nChannel держит канал карты.
pPacketBuffer содержит указатель на буфер приема.
nPacketSize содержит длину буфера приема.
Возвращаемые значения Если функция успешно, возвращаемое значение является контекстом этого соединения. Если функция не работает, возвращаемое значение равно -1.
Примечание
typedef struct {
BYTE m_bRemoteChannel;
BYTE m_bSendMode;
BYTE m_bImgFormat;
char * m_sIPAddress;
char * m_sUserName;
char * m_sUserPassword;
BOOL m_bUserCheck;
HWND m_hShowVideo;
} CLIENT_VIDEOINFO, * PCLIENT_VIDEOINFO;
m_bRemoteChannel содержит канал, к которому клиент хочет подключиться.
m_bSendMode поддерживает сетевой режим соединения.
m_bImgFormat: Формат изображения, 0 - видео основного канала, 1 - видео подканала.
m_sIPAddress содержит IP-адрес сервера.
m_sUserName содержит имя пользователя.
m_sUserPassword содержит пароль пользователя.
m_bUserCheck сохраняет значение, отправляет ли имя пользователя и пароль или нет.
m_hShowVideo содержит ручку для этого видео окна.
Если m_hShowVideo содержит NULL, клиент может записывать только без декодера.
Если m_bUserCheck является FALSE, мы отправим m_sUserName и m_sUserPassword как NULL, иначе мы отправим каждые 50 байт.
Длина m_sIPAddress и m_sUserName должна быть больше 50 байт.
ReadDataCallBack: Когда библиотека получает пакет с сервера, этот обратный вызов вызывается.
Мой код VB.Net:
Импортирует System.Runtime.InteropServices
Открытый класс Form1
Const WM_USER = &H400
Public Structure CLIENT_VIDEOINFO
Public m_bRemoteChannel As Byte
Public m_bSendMode As Byte
Public m_bImgFormat As Byte
Public m_sIPAddress As String
Public m_sUserName As String
Public m_sUserPassword As String
Public m_bUserCheck As Boolean
Public m_hShowVideo As Long 'hWnd
End Structure
Public Declare Function MP4_ClientSetNetPort Lib "hikclient.dll" (ByVal dServerPort As Integer, ByVal dClientPort As Integer) As Boolean
Public Declare Function MP4_ClientStartup Lib "hikclient.dll" (ByVal nMessage As UInteger, ByVal hWnd As System.IntPtr) As Boolean
<DllImport("hikclient.dll")> Public Shared Function MP4_ClientStart(ByVal Clientinfo As CLIENT_VIDEOINFO, ByRef ReadDataCallBack As CALLBACKdel) As Long
End Function
Public Delegate Sub CALLBACKdel(ByVal nPort As Long, <MarshalAs(UnmanagedType.LPArray)> ByRef pPacketBuffer As Byte(), ByVal nPacketSize As Long)
Public Sub CALLBACK(ByVal nPort As Long, <MarshalAs(UnmanagedType.LPArray)> ByRef pPacketBuffer As Byte(), ByVal nPacketSize As Long)
End Sub
Public mydel As New CALLBACKdel(AddressOf CALLBACK)
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim Clientinfo As New CLIENT_VIDEOINFO()
Clientinfo.m_bRemoteChannel = 0
Clientinfo.m_bSendMode = 0
Clientinfo.m_bImgFormat = 0
Clientinfo.m_sIPAddress = "193.168.1.100"
Clientinfo.m_sUserName = "1"
Clientinfo.m_sUserPassword = "a"
Clientinfo.m_bUserCheck = False
Clientinfo.m_hShowVideo = Me.Handle 'Nothing
MP4_ClientSetNetPort(850, 850)
MP4_ClientStartup(WM_USER + 1, Me.Handle)
MP4_ClientStart(Clientinfo, mydel)
End Sub
Конечный класс
вот несколько других примеров кода в:
С#
http://blog.csdn.net/nenith1981/archive/2007/09/17/1787692.aspx
В. Б.
://read.pudn.com/downloads70/sourcecode/graph/250633/MD%E5%AE%A2%E6%88%B7%E7%AB%AF%28VB%29/hikclient.bas__.htm
://read.pudn.com/downloads70/sourcecode/graph/250633/MD%E5%AE%A2%E6%88%B7%E7%AB%AF%28VB%29/Form1.frm__.htm
Delphi
://read.pudn.com/downloads91/sourcecode/multimedia/streaming/349759/Delphi_client/Unit1.pas__.htm
Это не полное решение вашей проблемы, но я бы начал с добавления StructLayoutAttribute (Sequential) в вашу структуру.
Imports System.Runtime.InteropServices
<StructLayout(LayoutKind.Sequential)> _
Public Structure CLIENT_VIDEOINFO
LayoutKind.Sequential
следует добавить LayoutKind.Sequential
, но это не может быть причиной ошибки, так как это фактически то, что .NET использует по умолчанию (по крайней мере, .NET 2.0 AFAIK).