vb调用c++dll回调函数问题!!!

sunghj 2019-01-17 04:43:49
大神们,再帮帮忙

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

函数调用部分代码
'下发卡号到网络盒子
Dim NetDvrCfgCond As NET_DVR_CARD_CFG_COND
NetDvrCfgCond.dwSize = LenB(NetDvrCfgCond)
NetDvrCfgCond.dwCardNum = 1
NetDvrCfgCond.byCheckCardNo = 1
NetDvrCfgCond.byRes1(0) = 0
NetDvrCfgCond.wLocalControllerID = 0
NetDvrCfgCond.byRes2(0) = 0
'锁号
NetDvrCfgCond.dwLockID = Val(Text6.Text)
NetDvrCfgCond.byRes3(0) = 0
Dim pRemoteConfigCallback As Long
pRemoteConfigCallback = PtrToLong(AddressOf fSetRemoteConfigCallback)
Dim dwInBufferLen As Long
dwInBufferLen = LenB(NetDvrCfgCond)
Dim pUserData As Long
pUserData = 0
Dim hStartRemoteConfig As Long
Dim lpInBuffer As Long
lpInBuffer = VarPtr(NetDvrCfgCond)
'启动远程配置。
hStartRemoteConfig = NET_DVR_StartRemoteConfig(iUserId, NET_DVR_SET_CARD_CFG_V50, lpInBuffer, dwInBufferLen, pRemoteConfigCallback, pUserData)
If hStartRemoteConfig = -1 Then
ErrorCode = NET_DVR_GetLastError
MsgBox "启动远程配置失败(" & ErrorCode & ")--下发到网络盒子!", vbOKOnly + vbExclamation, "提醒"
Call NET_DVR_Logout(iUserId)
Call NET_DVR_Cleanup
Exit Sub
End If


回调函数没有反应,过几秒后程序崩溃
...全文
483 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
舉杯邀明月 2019-01-20
  • 打赏
  • 举报
回复
引用 15 楼 sunghj 的回复:
回调函数工作了,正在调试中。。。。

呵呵,那剩下的都是你自己的事情了。

反正现在回调函数“已经被回调”了、也不会“程序崩溃”了…………
 这个问题,就算是已经给你解决了。
sunghj 2019-01-20
  • 打赏
  • 举报
回复
回调函数工作了,正在调试中。。。。
舉杯邀明月 2019-01-20
  • 打赏
  • 举报
回复
刚才注意到,你的代码中有这一句:
pRemoteConfigCallback = PtrToLong(AddressOf fSetRemoteConfigCallback)

不知道你的“PtrToLong( )”是如何定义的? 能否正确获取到函数地址……


你在调用 NET_DVR_StartRemoteConfig( )时,
 第5个参数直接写 AddressOf fSetRemoteConfigCallback 不就行了……
舉杯邀明月 2019-01-20
  • 打赏
  • 举报
回复
引用 12 楼 sunghj 的回复:
现在在现场调试,程序不在崩溃,但是回调函数没有反应,已经把function改为sub

首先你要确认你的“回调函数”是否被调用了啊!!!!

回调函数中,你不是有“Log信息”吗……
有输出没信息?
sunghj 2019-01-20
  • 打赏
  • 举报
回复
现在在现场调试,程序不在崩溃,但是回调函数没有反应,已经把function改为sub
sunghj 2019-01-19
  • 打赏
  • 举报
回复
引用 10 楼 舉杯邀明月 的回复:
其实在“回调函数”中要“监视、观察调试状态”的话, 用API:OutputDebugString( )才是正确选择,   比你用 MsgBxo、List.AddItem写Log信息等方法靠谱多了……
还没去现场调试,只是自己瞎琢磨,海康没有模拟环境,必须去现场调试,距离还比较远,条件又不允许长时间调试。
milaoshu1020 2019-01-18
  • 打赏
  • 举报
回复
可以用ATL写一个类,编写dll的回调函数并触发ATL类的事件.
然后在VB6中调用ATL写的这个类的对象.
我在编译chm的时候(也是需要写C的回调函数),就是这么做的.
舉杯邀明月 2019-01-18
  • 打赏
  • 举报
回复
其实在“回调函数”中要“监视、观察调试状态”的话,
用API:OutputDebugString( )才是正确选择,
  比你用 MsgBxo、List.AddItem写Log信息等方法靠谱多了……

舉杯邀明月 2019-01-18
  • 打赏
  • 举报
回复
你的“回调函数”中的消息框,弹出来了吗?

如果有弹出,把你的那几行消息框、List1.AddItem 都改成Debug.Print 再试试。
舉杯邀明月 2019-01-18
  • 打赏
  • 举报
回复
引用 7 楼 sunghj 的回复:
[quote=引用 6 楼 milaoshu1020 的回复:]
可以用ATL写一个类,编写dll的回调函数并触发ATL类的事件.
然后在VB6中调用ATL写的这个类的对象.
我在编译chm的时候(也是需要写C的回调函数),就是这么做的.

用vb实现有问题吗,如果没有问题,你说的这个方法好像有点麻烦。[/quote]
目前还没有搞定,还是要“崩溃”?

sunghj 2019-01-18
  • 打赏
  • 举报
回复
引用 6 楼 milaoshu1020 的回复:
可以用ATL写一个类,编写dll的回调函数并触发ATL类的事件. 然后在VB6中调用ATL写的这个类的对象. 我在编译chm的时候(也是需要写C的回调函数),就是这么做的.
用vb实现有问题吗,如果没有问题,你说的这个方法好像有点麻烦。
sunghj 2019-01-17
  • 打赏
  • 举报
回复
引用 4 楼 舉杯邀明月 的回复:
[quote=引用 2 楼 sunghj 的回复:]

    #define __stdcall 
    #define CALLBACK  
头文件是这样定义的,是不是CALLBACK 就等于__stdcall ?我百度也看到有说CALLBACK 就等于__stdcall . 另外回调函数里可以用msgbox吧,由于条件限制没法跟踪调试,所以msgbox也好list也好都是为跟踪回调函数到底有没有执行,以后肯定会去掉。
我说的回调函数应该是“Sub”,不应该是Function,你就无视了? 我说的“On Error”最好去掉,你也无视了? 函数的调用约定,可能是StdCall的没错。 [/quote] 我没无视啊,你说的这两个我都懂了,已经按照你说的改了,只是关于StdCall的不确定,所以只回了这个。
舉杯邀明月 2019-01-17
  • 打赏
  • 举报
回复
引用 2 楼 sunghj 的回复:

#define __stdcall
#define CALLBACK

头文件是这样定义的,是不是CALLBACK 就等于__stdcall ?我百度也看到有说CALLBACK 就等于__stdcall .
另外回调函数里可以用msgbox吧,由于条件限制没法跟踪调试,所以msgbox也好list也好都是为跟踪回调函数到底有没有执行,以后肯定会去掉。



我说的回调函数应该是“Sub”,不应该是Function,你就无视了?
我说的“On Error”最好去掉,你也无视了?

函数的调用约定,可能是StdCall的没错。

sunghj 2019-01-17
  • 打赏
  • 举报
回复
这个是c++头文件的定义

typedef void(CALLBACK *fRemoteConfigCallback)(DWORD dwType, void* lpBuffer, DWORD dwBufLen, void* pUserData);
sunghj 2019-01-17
  • 打赏
  • 举报
回复

    #define __stdcall 
    #define CALLBACK  
头文件是这样定义的,是不是CALLBACK 就等于__stdcall ?我百度也看到有说CALLBACK 就等于__stdcall . 另外回调函数里可以用msgbox吧,由于条件限制没法跟踪调试,所以msgbox也好list也好都是为跟踪回调函数到底有没有执行,以后肯定会去掉。
舉杯邀明月 2019-01-17
  • 打赏
  • 举报
回复
我觉得:
1. 你在“回调函数”内使用“On Error语句”,应该是个比较严重的问题……
  我觉得,这种“身份”的东西,最好别用这个(尽量避免,能不用就别用);
    对于“异常”,最好是各种“条件校验”,有“问题”就拒绝操作、
    并用“数值代码”反映“遇到什么‘不合要求’的问题”。
 (设法把值回传出去,象那些“指针”应该是可以写输出值的,只是要看“调用协议”咋样)
  其次的话,在回调函数内也最好不要去操作“控件”(当然多数情况下可能也没问题)。

2. 这个“回调函数”是void的……你在VB中应该是用一个Sub而不是Function。
  更何况你这个Function还搞成 Variant类型的…… 

3. 它的“回调”是StdCall约定的吗?
  如果是,在VB中的直接实现就没问题;如果不是,可能得用“汇编”包装一下。
加密狗系列—软件狗 面向单机环境的低成本加密方案   软件狗是使用在计算机并行口和USB口上的用于软件保护的硬件产品。软件狗采用端口噪声技术,提供100字节的掉电保护存储器,具备反跟踪能力,是经济实用软件保护解决方案的首选。软件狗开发套件有两种选型:并口型和USB型。软件开发商可以采用多种方法保护软件,防止软件被非法拷贝使用。软件狗开发套件由:软件狗、加密接口、开发商工具等组成。 1.软件狗 软件狗指安装在并口上或 USB 口上的硬件狗。软件狗是一个可编程、可读写的存储设备,具有 100 个字节的数据存储区。如果软件狗插在计算机上,您可以通过相应的加密接口函数或开发商工具对软件狗进行访问。 2.加密接口 软件狗开发套件提供的加密接口是一套包含各种开发语言的程序接口模块,可以嵌在程序的源代码中。您可以在您程序中使用软件狗开发套件提供的加密接口对软件狗进行操作。 3.开发商工具(DogEdt32.EXE) 软件狗开发商工具可以使开发商方便地对软件狗存储区进行编辑、读取系列号以及连续初始化等操作。 工作原理: 开发商程序通过调用软件狗开发套件提供的接口模块对软件狗操作,软件狗响应该操作并通过接口模块将相应数据返回给开发商程序。开发商程序可以对返回值进行判定并采取相应的动作。如果返回无效的响应,表明没有正确的软件狗,开发商可以将应用程序终止运行。 简要示意如下: 软件狗开发套件提供了两种加密方案:使用 Obj 、 DLL 、 ActiveX 控件或者直接使用外壳工具,请根据您的需求选择方案。 加密方案一:使用 Obj 、 DLL 、 ActiveX 控件 Obj 、 DLL 、 ActiveX 控件提供了操作软件狗的接口函数,您可以直接在应用程序的源代码里加入这些接口函数的调用,来保护您的一个或者多个软件,然后重新编译您的应用程序。 由您来设置应用程序中调用加密接口的次数以及没有发现软件狗采取的措施。原则上您调用、设置的加密接口越多将更有利于阻止潜在破坏您的软件保护。 加密方案二:使用外壳工具 使用外壳工具对软件保护是一种快速、简单的保护方案。它不象使用接口函数需要对源代码进行改动,而是自动给您的可执行应用程序加了一个保护层。在程序开始运行和运行当中会自动地访问软件狗是否存在。假如软件狗不存在,用户将看到一个错误提示,该应用程序将不能运行。 产品特点: 软件狗开发套件适用于 DOS 、 Windows 3X/9X/ME/NT/2000/XP 、 Linux 操作系统,支持几乎所有主流编程语言、开发工具。软件狗的主要特点如下: 数据交换随机噪声技术 有效地对抗逻辑分析仪及各种调试工具的攻击,完全禁止软件仿真程序模拟并口的数据。 迷宫技术 在 RC-DL 函数入口和出口之间包含大量复杂的判断跳转干扰代码,动态改变执行次序,提升 RC-DL 的抗跟踪能力。 时间闸 硬件狗内部设有时间闸,各种操作必须在规定的时间内完成。硬件狗正常操作用时很短,但跟踪时用时较长,超过规定时间,硬件狗将返回错误结果。 AS 技术 API 函数调用与 SHELL 外壳加密相结合的方式,同时使用能够达到极高的加密强度。 RC-DL 开发套件在外壳加密工具中与调用的 API 函数建立了对应关系。这样处理后,程序中调用的 API 函数只有在有外壳的情况下才能正确运行,而外壳本身隐蔽了对 API 函数的调用。 抗共享 可以通过编程的方式实现对抗并口共享器。 存储器 提供 100 字节掉电保持数据存储区供开发商存放关键数据、配置参数等信息,可通过 RC-DL 开发商工具或接口函数对存储区进行读写。 改良的硬件驱动程序 驱动程序的安装及发布更加方便、快捷,开发商只需使用 InstDrv.exe 安装驱动程序,硬件即可正常工作。 崭新的硬件狗编辑工具 DogEdt32.exe 集成了原有 DogEdt32.exe 、 Reveal.exe 、 Convert.exe 三个工具,并新增错误码查询功能,令硬件狗编辑调试过程更趋简捷、顺畅。 高强度动态库加密方式 在原有加密方式基础上,新增 C 语言高强度动态库加密方式,并有效运用动态库认证安全机制,确保动态库调用具有无与伦比的安全可靠性。 支持 ActiveX 控件 开发商可以在网页中或 VB 、 VC 中使用 ActiveX 控件对硬件狗进行操作。 Linux 模块 提供了针对 Linux 内核 2.2 和 2.4 版本驱动程序,开发商可以使用 Linux 模块保护运行于 Linux 操作系统上的应用程序。 新增功能: 软件狗开发套件 3.0 版新增功能在软件狗开发套件 V3.0 中,新增了与原并口硬件完全兼容的 UDA 型 USB 软件狗。 USB 软件狗也提供了 100 字节的用户存储区。新的开发商工具( DogEdt32.EXE )或接口函数既可以老的并口硬件,也可以对新的 USB 硬件进行操作。 已安装了软件狗开发套件 V2.1 的老用户如要使用 UDA 型 USB 软件狗,必须重新安装软件狗开发套件 V3.0 ,以安装 UDA 型 USB 软件狗的驱动程序并更新开发套件的 OBJ 。 开发商如果使用 WIN32 模块,在 Windows98 或更高版本( WindowsME/2K/XP )下既可以使用 USB 软件狗也可以使用并口软件狗。目前暂不提供 USB 软件狗在 Windows NT4 上的驱动程序,即在 Windows NT4 操作系统上,目前只能使用并口软件狗。 在安装 Linux2.4 以上内核的 Linux 系统中,既可以使用并口软件狗也可以使用 USB 软件狗。 WIN16 、 DOS16 、 DOS32 模块本次没有改动,仍只支持并口软件狗。 软件狗开发套件 目前最新版本为 v3.0 支持并口硬件 RC-DL (现已更名为 PDL ) , 支持 USB 口硬件 UDA 适用语言环境: 并口型软件狗: DOS16: C , C++, FORTRAN, ASM, Pascal, BASIC ( BASCOM, Quick,True, Turbo ) , FOXPRO, Clipper, Foxbase, Dbase, EXE/COM 文件;DOS32: C, C++ ( High, NDP, Watcom ), FORTRAN ( NDP, PowerStation,Watcom) , EXP 文件; Win16: C, C++ ( Borland, Visual ), Visual BASIC, FOXPRO, PowerBuilder,Delphi Win32: C, C++ ( Visual, Borland, C++Builder, MFC ), FORTRAN ( LAHEY,PowerStation, Visual ), Java, VisualBasic, VisualFoxpro, PowerBuilder,Delphi,JavaScript, VBScript, VBA, InstallShield, AutoCAD, .NET 等。 Linux: C, C++, Java USB 型软件狗: Win32: C, C++ ( Visual, Borland, C++Builder, MFC), FORTRAN ( LAHEY, PowerStation, Visual ), Java, VisualBasic, VisualFoxpro, PowerBuilder, Delphi , JavaScript, VBScript, VBA, InstallShield, AutoCAD, .NET 等等。 Linux: C, C++, Java 适用操作系统: 并口型软件狗: DOS , Windows 3.x / 9x / ME / NT / 2000 / XP / Sever 2003 LINUX (Red hat 内核 2.2 / 2.4) USB 型软件狗: Windows 98 / ME / 2000 / XP / Sever 2003 LINUX (Red hat 内核 2.2 / 2.4) 开发商升级注意事项: 并口 RC-DL (现已更名为 PDL )型软件狗的软件软件狗开发套件 V3.0 与原 DJ/DK 完全兼容,即使用软件狗开发套件 V3.0 的驱动程序、模块及工具,可以正常操作 DJ/DK 型软件狗。所以建议使用原 DJ/DK 软件的开发商将您的驱动程序、模块及工具全部用软件狗开发套件 V3.0 (光盘版)套件升级。 如果您仍旧使用原有的 DI/DJ/DK 驱动程序、模块及工具,在 DOS 、 Windows 9X/NT/2000 下对 RC-DL 只能做读操作,写操作将失败。如果您不想改动已发行的软件,而还要使用 RC-DL 型软件狗,只升级驱动程序也可以,但您的程序必须是 WIN32 程序。如果您加密的程序是 DOS16 、 DOS32 或 WIN16 程序,您必须升级新的模块及工具,否则将无法对 RC-DL 型软件狗进行写操作。 使用方法: 1.对 EXE 文件 ( 或 COM 文件 ), 利用配套软件中的 EXE 文件加密工具加密。 2 对数据库文件 (PRC 、 FOX 、 APP 、 DBF), 利用配套软件中的加密工具加密。 3 对于 C 语言及其它编译型语言,配套软件中提供可链接的模块文件 (OBJ 文件 ) , 模块文件中提供两个函数 :(1) 写数据 ; ⑵读数据。开发商可在要加密软件的源码中加入适当的调用语句,对软件狗进行读写操作,以确定对应的软件狗是否存在,从而决定程序是否继续运行。对加入软件狗函数调用的源程序编译后,链接时加上软件狗的模块文件 (OBJ) 即可。

7,763

社区成员

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

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