【问题标题】:VB6 how to make an EXE wait for events to complete in DLLVB6如何使EXE等待DLL中的事件完成
【发布时间】:2017-07-28 02:50:50
【问题描述】:

简介

我有一个使用事件与硬件设备交互的 DLL。总之,我希望主 EXE 应用程序在硬件接口 DLL 对硬件执行其操作时在各个点等待,然后通过另一个 DLL 将结果传递回主调用应用程序 (见上图)

模块结构

EXE ; 只是一个简单的测试应用程序,它调用 Calling DLL 中的各种函数,进而调用 Operating DLL 中的函数。 最后一个设备 DLL 只是制造商提供的普通硬件分发驱动程序类型 DLL。

调用 DLL ; 是一个通用 dll,它为我的应用程序执行各种处理,包括根据需要动态加载各种硬件操作 DLL,传回从各种和更具体的操作 DLL 转换而来的公共信息。我猜它有点像漏斗。

操作 DLL ; 每个连接到 PC 的硬件设备都存在。它可以用于任何设备,例如网络摄像头、扫描仪等。这些 DLL 的一端与通用调用 DLL 通信,另一端与制造商 DLL 通信。

摘要

我能够将操作 DLL 编译为 EXE 以进行测试。在这种状态下,它有一个带有几个按钮的表单。这些按钮是“打开”“关闭”“Scan1”“Scan2” 当操作 DLL 编译为 DLL 时,通过调用 DLL 调用这些相同的“按钮”。希望这是有道理的。 因此,换句话说,我可以在本机模式下将操作 DLL 作为 EXE 进行测试 - 它运行良好,并且我可以将其编译为 DLL 以供调用 DLL 使用。

Scan1 和 Scan2 函数使用事件处理。

因此,作为 EXE 的操作 DLL,我可以使用操作 DLL 的内部调用通过设备 dll 打开并连接到设备。工作正常,事件工作正常,应用程序步骤正常。这主要是由于我猜测操作 DLL 中表单布局的结构,这正是每个按钮所必须的。它仍然在内部使用事件,但在外部(在表单级别)它只需要按照我选择的 Scan1 或 Scan2 按钮执行该循环。

问题

问题是这样的,当操作 DLL 被编译为一个 DLL 时,指令是由上一级的调用 DLL 发出的。调用 DLL 有一个代码路径,其中有一个对操作 DLL 的调用,告诉它 Scan1。 这很好,但是,调用 DLL 会继续前进,不会等待操作 DLL 完成并返回所需的数据。 因此调用 DLL 失败。它只是匆匆忙忙,没有收到任何数据返回。

代码

这是“调用 DLL - 它消耗操作 DLL”

** This function is used to call the Operating DLL and run the Events
**
Private Function IScanDevice_Scan1(Collections As Template, ByVal ScanPurpose As ScanPurposes, ByVal ScanTimeout As Integer, Region As ScanRegion) As Scan_ResultCodes

'* call the Operating DLL processes which use Events 
'*
ScanCollected = Scan1(Collections, ScanPurpose, mScanTimeout, mRegion)


'* The following should only execute after all Operating DLL stuff completes
'*        
   MsgBox ("Scan1 Call for Operating DLL completed)
   Call printResults
.
.
End Function

这是“操作 DLL - 也可以编译为 EXE 进行测试”

Option Explicit

Public WithEvents obj As OPOSBiometrics    

''
' This implements the IScanDevice interface.

Implements IScanDevice

.
.

** Used by the Calling DLL    
Public Function IScanDevice_Scan1(Collections As BBScan.Template, ByVal ScanPurpose As BBScan.ScanPurposes, ByVal ScanTimeout As Integer, Region As BBScan.ScanRegion) As BBScan.Scan_ResultCodes
  .
  RC = TestDemo.DoBeginCapture
  .
  .

** This is called from the Form internally when in EXE mode
** and called from the Calling DLL via IScanDevice_Scan1 above
Public Function DoBeginCapture() As RC_ResultCodes
.
  obj.DataEventEnabled = True
  dataEvent = dEvent.BeginCapture
. 
.
Exit Function


'**Event Processing**    
Public Sub obj_DataEvent(ByVal Status As Long)

On Error GoTo Error_DataEvent

Select Case dataEvent

   Case dEvent.Identify
         dataEvent = dEvent.None

   Case dEvent.BeginVerify
CoreScan = obj.BIR
 ret = obj.EndCapture()
If ret = OposSuccess Then
            .
Else
.
End If

            obj.DataEventEnabled = True
dataEvent = dEvent.None

    Case dEvent.Register

            ret = obj.EndCapture()
         If ret = OposSuccess Then
.
         Else
.
         End If

obj.DataEventEnabled = True

         dataEvent = dEvent.None

End Select
.
.
End Sub 

因此,总而言之,调用 DLL 会显示 MsgBox 并尝试在操作 DLL IScanDevice_Scan1 函数未完成的情况下运行 printReport 函数。

【问题讨论】:

    标签: events vb6


    【解决方案1】:

    我不清楚您从第一次调用_Scan1 后返回的位置/时间。如果您在调用 BeginCapture 后立即返回,那么您在被调用者中发生任何内部处理或事件之前将控制权返回给调用者,并且程序流程从那里继续。

    如果重要的是在调用 DLL 中暂停处理直到被调用 DLL 发生某些事情,您必须在被调用 DLL 中保留控制点,或者在调用 DLL 中等待调用者发出某些事件信号.

    【讨论】:

    • 感谢您的回复。正确,DLL 只是处理主要是与硬件相关的输入接口,然后它退出并返回一些信息给调用 DLL。同意你的观点,但是除了我想避免的处理 DLL 的几秒钟内的硬等待之外,我看不到在事件处理过程中将注意力集中在 DLL 上的方法。有没有办法解决这个问题?
    • @GarthJones 在被调用的 DLL 返回后,您可以在调用者中无限期等待,直到被调用的 DLL 引发事件或其他信号。这假设有一种方法可以知道所有处理何时完成。如果您无法通过 VB 事件完成此操作,则使用 CreateEvent 向系统注册一个事件,在调用者中调用 WaitForSingleEvent,并在被调用者中发出事件信号。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-24
    • 2021-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-19
    相关资源
    最近更新 更多