API调用问题请教!!!!!

sunghj 2019-01-10 11:25:24
海康威视最新的SDK有人用过吗,登陆注册的函数调用报参数传递错误(参数错误。SDK接口中给入的输入或输出参数为空,或者参数格式或值不符合要求。)。下面是C++代码

LONG NET_DVR_Login_V40( LPNET_DVR_USER_LOGIN_INFO pLoginInfo,
LPNET_DVR_DEVICEINFO_V40 lpDeviceInfo);

struct{
char sDeviceAddress[NET_DVR_DEV_ADDRESS_MAX_LEN];
BYTE byUseTransport;
WORD wPort;
char sUserName[NET_DVR_LOGIN_USERNAME_MAX_LEN];
char sPassword[NET_DVR_LOGIN_PASSWD_MAX_LEN];
fLoginResultCallBack cbLoginResult;
void *pUser;
BOOL bUseAsynLogin;
BYTE byProxyType;
BYTE byUseUTCTime;
BYTE byLoginMode;
BYTE byHttps;
LONG iProxyID;
BYTE byRes3[120];
}NET_DVR_USER_LOGIN_INFO,*LPNET_DVR_USER_LOGIN_INFO;

struct{
NET_DVR_DEVICEINFO_V30 struDeviceV30;
BYTE bySupportLock;
BYTE byRetryLoginTime;
BYTE byPasswordLevel;
BYTE byProxyType;
DWORD dwSurplusLockTime;
BYTE byCharEncodeType;
BYTE bySupportDev5;
BYTE byLoginMode; BYTE byRes2[253];
}NET_DVR_DEVICEINFO_V40,*LPNET_DVR_DEVICEINFO_V40;

struct{
BYTE sSerialNumber[SERIALNO_LEN];
BYTE byAlarmInPortNum;
BYTE byAlarmOutPortNum;
BYTE byDiskNum;
BYTE byDVRType;
BYTE byChanNum;
BYTE byStartChan;
BYTE byAudioChanNum;
BYTE byIPChanNum;
BYTE byZeroChanNum;
BYTE byMainProto;
BYTE bySubProto;
BYTE bySupport;
BYTE bySupport1;
BYTE bySupport2;
WORD wDevType;
BYTE bySupport3;
BYTE byMultiStreamProto;
BYTE byStartDChan;
BYTE byStartDTalkChan;
BYTE byHighDChanNum;
BYTE bySupport4;
BYTE byLanguageType;
BYTE byVoiceInChanNum;
BYTE byStartVoiceInChanNo;
BYTE byRes3[2];
BYTE byMirrorChanNum;
WORD wStartMirrorChanNo;
BYTE byRes2[2];
}NET_DVR_DEVICEINFO_V30,*LPNET_DVR_DEVICEINFO_V30;

这是Callback Function
typedef void(CALLBACK *fLoginResultCallBack)(
LONG lUserID,
DWORD dwResult,
LPNET_DVR_DEVICEINFO_V30 lpDeviceInfo,
void *pUser
);

下边是我修改vb的代码

Global Const NET_DVR_DEV_ADDRESS_MAX_LEN = 129
Global Const NET_DVR_LOGIN_USERNAME_MAX_LEN = 64
Global Const NET_DVR_LOGIN_PASSWD_MAX_LEN = 64
Global Const SERIALNO_LEN = 48 '序列号长度

Type NET_DVR_USER_LOGIN_INFO
sDeviceAddress As String * NET_DVR_DEV_ADDRESS_MAX_LEN
byUseTransport As Byte
wPort As Integer
sUserName As String * NET_DVR_LOGIN_USERNAME_MAX_LEN
sPassword As String * NET_DVR_LOGIN_PASSWD_MAX_LEN
cbLoginResult As Long
pUser As Long
bUseAsynLogin As Boolean
byProxyType As Byte
byUseUTCTime As Byte
byLoginMode As Byte
byHttps As Byte
iProxyID As Long
byRes3(120) As Byte
End Type

Type NET_DVR_DEVICEINFO_V30
sSerialNumber(SERIALNO_LEN) As Byte
byAlarmInPortNum As Byte
byAlarmOutPortNum As Byte
byDiskNum As Byte
byDVRType As Byte
byChanNum As Byte
byStartChan As Byte
byAudioChanNum As Byte
byIPChanNum As Byte
byZeroChanNum As Byte
byMainProto As Byte
bySubProto As Byte
bySupport As Byte
bySupport1 As Byte
bySupport2 As Byte
wDevType As Integer
bySupport3 As Byte
byMultiStreamProto As Byte
byStartDChan As Byte
byStartDTalkChan As Byte
byHighDChanNum As Byte
bySupport4 As Byte
byLanguageType As Byte
byVoiceInChanNum As Byte
byStartVoiceInChanNo As Byte
byRes3(2) As Byte
byMirrorChanNum As Byte
wStartMirrorChanNo As Integer
byRes2(2) As Byte
End Type

Type NET_DVR_DEVICEINFO_V40
struDeviceV30 As NET_DVR_DEVICEINFO_V30
bySupportLock As Byte
byRetryLoginTime As Byte
byPasswordLevel As Byte
byProxyType As Byte
dwSurplusLockTime As Long
byCharEncodeType As Byte
bySupportDev5 As Byte
byLoginMode As Byte
byRes2(253) As Byte
End Type

'设备登陆
Public Declare Function NET_DVR_Login_V40 Lib "HCNETSDK.dll" ( _
ByRef pLoginInfo As NET_DVR_USER_LOGIN_INFO, _
ByRef lpDeviceInfo As NET_DVR_DEVICEINFO_V40) As Long

下面是vb调用的代码

Dim pLoginInfo As NET_DVR_USER_LOGIN_INFO
Dim lpDeviceInfo As NET_DVR_DEVICEINFO_V40
'是否异步登录:0- 否,1- 是
pLoginInfo.bUseAsynLogin = 0

'ISAPI协议登录时是否启用HTTPS(byLoginMode为1时有效):0- 不启用,1- 启用,2- 自适应(设备支持协议类型未知时使用,一般不建议)
pLoginInfo.byHttps = 0

'登录模式(不同模式具体含义详见“Remarks”说明):0- SDK私有协议,1- ISAPI协议,2- 自适应(设备支持协议类型未知时使用,一般不建议)
pLoginInfo.byLoginMode = 0

'代理服务器类型:0- 不使用代理,1- 使用标准代理,2- 使用EHome代理
pLoginInfo.byProxyType = 0
pLoginInfo.byRes3(0) = 0

'是否启用能力集透传:0- 不启用透传,默认;1- 启用透传
pLoginInfo.byUseTransport = 0

'是否使用UTC时间:0- 不进行转换,默认;1- 输入输出UTC时间,SDK进行与设备时区的转换;2- 输入输出平台本地时间,SDK进行与设备时区的转换
pLoginInfo.byUseUTCTime = 0

'登录状态回调函数,bUseAsynLogin 为1时有效
Dim cbLoginResult As Long
pLoginInfo.cbLoginResult = cbLoginResult

'代理服务器序号,添加代理服务器信息时相对应的服务器数组下表值
pLoginInfo.iProxyID = 0

pLoginInfo.sDeviceAddress = Text1.Text
pLoginInfo.wPort = Text2.Text
pLoginInfo.sUserName = Text3.Text
pLoginInfo.sPassword = Text4.Text

'用户数据
Dim pUser As Long
pLoginInfo.pUser = pUser
Dim iUserId As Long

'登陆设备
iUserId = NET_DVR_Login_V40(pLoginInfo, lpDeviceInfo)
If iUserId = -1 Then
ErrorCode = NET_DVR_GetLastError()
MsgBox "登陆失败(" & ErrorCode & ")!", vbOKOnly + vbExclamation, "提醒"
Call NET_DVR_Cleanup
Exit Sub
End If

...全文
625 11 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
sunghj 2019-01-17
  • 打赏
  • 举报
回复
大神,再帮帮忙

LONG NET_DVR_StartRemoteConfig(  LONG                     lUserID,
  DWORD                    dwCommand,  LPVOID                   lpInBuffer,
  DWORD                    dwInBufferLen,
  fRemoteConfigCallback    cbStateCallback,  LPVOID                   pUserData
);

Callback Function
typedef void(CALLBACK *fRemoteConfigCallback)(
  DWORD    dwType,
  void     *lpBuffer,
  DWORD    dwBufLen,
  void     *pUserData
);
这是vb的定义

'启用长链接
Public Declare Function NET_DVR_StartRemoteConfig Lib "HCNETSDK.dll" ( _
                ByVal lUserID As Long, _
                ByVal dwCommand As Long, _
                ByVal lpInBuffer As Long, _
                ByVal dwInBufferLen As Long, _
                ByVal cbStateCallback As Long, _
                ByVal pUserData As Long) As Long

回调函数
'下发卡号回调函数
Public Function fSetRemoteConfigCallback(ByVal dwType As Long, ByVal lpBuffer As Long, ByVal dwBufLen As Long, ByVal pUserData As Long)
On Error GoTo ErrFlag
    MsgBox "fSetRemoteConfigCallback"
    List1.AddItem "fSetRemoteConfigCallback(dwType=" & dwType & ")!", 0
    If dwType <> NET_SDK_CALLBACK_TYPE_STATUS Then
        Exit Function
    End If
    Dim dwStatus As Long
    CopyMemory VarPtr(dwStatus), lpBuffer, 4   '复制lpBuffer的内存到dwStatus的指针处
    If dwStatus = NET_SDK_CALLBACK_STATUS_SUCCESS Then
        bSetCardCfgFinish = True
    End If
    List1.AddItem "fSetRemoteConfigCallback(dwStatus=" & dwStatus & ")!", 0
Exit Function
ErrFlag:
    MsgBox "fSetRemoteConfigCallback--" & Err.Description, vbOKOnly + vbExclamation, "提醒"
End Function
sunghj 2019-01-17
  • 打赏
  • 举报
回复
最终还是卡到了回调函数这,回调函数没有响应,但是等几秒后就崩溃了。
sunghj 2019-01-14
  • 打赏
  • 举报
回复
引用 8 楼 舉杯邀明月 的回复:
[quote=引用 7 楼 sunghj 的回复:] [quote=引用 6 楼 舉杯邀明月 的回复:] API函数参数中所有的“某某指针”,在VB中都可以定义成 as long ,  然后在调用时,按 ByVal 传递入相应的“正确地址”就行了。 这种方式,是“百分百兼容”的。
好的,谢谢[/quote] 问题都已经解决了,就结贴吧。 [/quote] 我本想等把这个项目弄完在结贴,因为后面还有几个类似的函数调用正在调试,对于c++转vb确实不太熟悉。这个贴先结掉,下次有问题要继续向您请教!
舉杯邀明月 2019-01-13
  • 打赏
  • 举报
回复
引用 7 楼 sunghj 的回复:
[quote=引用 6 楼 舉杯邀明月 的回复:]
API函数参数中所有的“某某指针”,在VB中都可以定义成 as long ,
 然后在调用时,按 ByVal 传递入相应的“正确地址”就行了。

这种方式,是“百分百兼容”的。

好的,谢谢[/quote]
问题都已经解决了,就结贴吧。

sunghj 2019-01-12
  • 打赏
  • 举报
回复
引用 6 楼 舉杯邀明月 的回复:
API函数参数中所有的“某某指针”,在VB中都可以定义成 as long ,  然后在调用时,按 ByVal 传递入相应的“正确地址”就行了。 这种方式,是“百分百兼容”的。
好的,谢谢
舉杯邀明月 2019-01-12
  • 打赏
  • 举报
回复
API函数参数中所有的“某某指针”,在VB中都可以定义成 as long ,
 然后在调用时,按 ByVal 传递入相应的“正确地址”就行了。

这种方式,是“百分百兼容”的。
sunghj 2019-01-12
  • 打赏
  • 举报
回复
引用 3 楼 舉杯邀明月 的回复:
另外,你贴出来的VB代码第36行,极可能是错误的! 按你那样写,pLoginInfo.pUser会是个“空指针”………… 不过我也从你上面的那些“内容”中看出这个成员有什么用处、应该如何使用及传递。 如果说是“指向用户名”的,它的结构成员中不是已经有“用户名”了吗……   并且一般这种情况下也应该是char * 类型而不是 void * 类型。 你自己查一下文档吧。
之前的问题解决了,非常感谢。现在又遇到一个问题,一个新的函数

BOOL NET_DVR_SendRemoteConfig(  
  LONG     lHandle,  
  DWORD    dwDataType,
  char     *pSendBuf,  
  DWORD    dwBufSize);

就是第三个参数char *pSendBuf,实际这个参数可以传递不同的结构体,其中一个是这样的
struct{  
  DWORD                       dwSize;
  DWORD                       dwModifyParamType;
  BYTE                        byCardNo[ACS_CARD_NO_LEN];
  BYTE                        byCardValid;
  BYTE                        byCardType;
  BYTE                        byLeaderCard;
  BYTE                        byUserType;;
  BYTE                        byDoorRight[MAX_DOOR_NUM];
  NET_DVR_VALID_PERIOD_CFG    struValid;
  BYTE                        byBelongGroup[MAX_GROUP_NUM];
  BYTE                        byCardPassword[CARD_PASSWORD_LEN];
  WORD                        wCardRightPlan[MAX_DOOR_NUM][MAX_CARD_RIGHT_PLAN_NUM];
  DWORD                       dwMaxSwipeTime;
  DWORD                       dwSwipeTime;
  WORD                        wRoomNumber;
  SHORT                       wFloorNumber;
  DWORD                       dwEmployeeNo;
  BYTE                        byName[NAME_LEN];
  WORD                        wDepartmentNo;
  WORD                        wSchedulePlanNo;
  BYTE                        bySchedulePlanType;
  BYTE                        byRes2[3];  
  DWORD                       dwLockID;
  BYTE                        byLockCode[MAX_LOCK_CODE_LEN];
  BYTE                        byRoomCode[MAX_DOOR_CODE_LEN];
  DWORD                       dwCardRight;
  DWORD                       dwPlanTemplate;
  DWORD                       dwCardUserId;
  BYTE                        byCardModelType;
  BYTE                        byRes3[83];
}NET_DVR_CARD_CFG_V50,*LPNET_DVR_CARD_CFG_V50;

不知道这个函数NET_DVR_SendRemoteConfig,在vb里要如何定义,我想定义成这样:
Public Declare Function NET_DVR_SendRemoteConfig Lib "HCNETSDK.dll" (ByVal lHandle As Long, ByVal dwDataType As Long, ByVal pSendBuf As long, _
        ByVal dwBufSize As Long) As Long

用VarPrt得到NET_DVR_CARD_CFG_V50结构的地址,然后传给pSendBuf,不知道是否可行。

sunghj 2019-01-11
  • 打赏
  • 举报
回复
有大神帮忙看看吗
sunghj 2019-01-11
  • 打赏
  • 举报
回复
to: 舉杯邀明月 谢谢,我试试
舉杯邀明月 2019-01-11
  • 打赏
  • 举报
回复
另外,你贴出来的VB代码第36行,极可能是错误的!

按你那样写,pLoginInfo.pUser会是个“空指针”…………

不过我也从你上面的那些“内容”中看出这个成员有什么用处、应该如何使用及传递。
如果说是“指向用户名”的,它的结构成员中不是已经有“用户名”了吗……
  并且一般这种情况下也应该是char * 类型而不是 void * 类型。


你自己查一下文档吧。
舉杯邀明月 2019-01-11
  • 打赏
  • 举报
回复
你在VB中定义的“数据类型”不正确。


另外,C++代码中的 char类型成员,建议在VB6中也用 Byte类型代替,而不是用 String * xxxx 。
比如,先“按你的思路”来说:
C++代码的: char sDeviceAddress[NET_DVR_DEV_ADDRESS_MAX_LEN];
建议这样改: sDeviceAddress(NET_DVR_DEV_ADDRESS_MAX_LEN) as byte


另外,就是“Byte数组成员”的定义问题:
比如:
 BYTE byRes3[120];   你改为 byRes3(120) As Byte
 BYTE sSerialNumber[SERIALNO_LEN]; 你改为 sSerialNumber(SERIALNO_LEN) As Byte
这些都是错误的!
(当然:你在模块开头写了 Option Base 1除外。 不过我估计没这可能性。)
C++中那个方括号中的代表“元素数量”;而VB中定义数组,括号中是“数组上界”。
因为默认是下标从0开始,这样会比你“预想”的要多一个元素出来,会造成“结构错位”的!
例如byRes3[120]; 结果是byRes3区域长度是120字节;
  而你 byRes3(120) As Byte后,结果 byRes3区域的长度是121字节了!
如果是“最后一个成员”也许没事;否则话,就造成其它成员的“位置”错位了。

所以,(默认情况下)正确的是:
BYTE byRes3[120];   应为 byRes3(119) As Byte
BYTE sSerialNumber[SERIALNO_LEN]; 应为 sSerialNumber(SERIALNO_LEN-1) As Byte

同样,上面我说的 char sDeviceAddress[NET_DVR_DEV_ADDRESS_MAX_LEN];
 也应该这样改: sDeviceAddress(NET_DVR_DEV_ADDRESS_MAX_LEN-1) as byte

7,785

社区成员

发帖
与我相关
我的任务
社区描述
VB 基础类
社区管理员
  • VB基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧