为什么我需要WaitFor'/ MsgBox来防止在从C ++ DLL获取数据的VB6 exe中崩溃

时间:2014-03-20 13:31:54

标签: debugging dll vb6

我是一般的编程新手,所以请耐心等待。

我正在使用的这个VB6程序(我在工作中是新手)使用较旧但更新的Borland C ++ DLL(我也在更新)来获取零件清单。

在VB6 IDE的调试模式下一切正常,但是当我创建一个实际的可执行文件并尝试它时,它会崩溃。这个问题的“修复”已经在我到达这里之前已经实现了几年,他们添加了一堆WaitFor函数调用“慢下来VB6,这样它就可以在继续之前完成从DLL的读取。”

奇怪的是,我正在通过对特定部分放置一些硬编码的if-checks并将其放入DLL来更新VB6代码,因为它们无法使先前更新的Borland C ++ DLL。当然,副作用是VB6代码运行得更快。

我把问题缩小到简单的计时。有一个部分,如果我只是添加一个简单的MsgBox,它不会崩溃,但WaitFor,即使设置为100000 ......也行不通。

所以我的问题是,如果没有任意添加WaitFors等,我可以阻止VB6代码继续运行而不会完成读取。这似乎是一个糟糕的做法,我将在这家公司工作一段时间并且不要我想继续这种趋势。

谢谢!


更新

这样做代替MsgBox似乎也可以使它工作:

Dim x as Long
Dim y as Long
For x= 1 to 500
    y = y + 1
Next

简单地添加废话可以解决问题。


WaitFor函数:

On Error Resume Next
Static dLastDoevents  As Double
Dim SleepyTime        As Integer:   SleepyTime = 20     'set "Sleep peroid" in milliseconds (this is also the resolution of the doevents rate)
Dim DoEventsRate      As Integer:   DoEventsRate = 200     'set "DoEvents rate" in milliseconds
Dim iSleepTimes       As Integer:   iSleepTimes = Int(MilliSeconds / SleepyTime)
Dim msLeftOver        As Integer:   msLeftOver = (MilliSeconds - (iSleepTimes * SleepyTime))
Dim dNow              As Double
Dim i                 As Integer

If MilliSeconds < 0 Then MilliSeconds = 0

dNow = Timer
If dNow > (dLastDoevents + (DoEventsRate / 1000)) Or dLastDoevents = 0 Or dLastDoevents > dNow Then
  DoEvents                  'DoEvents if it's been long enough according to the DoeventsRate
  dLastDoevents = Timer
End If

If iSleepTimes > 0 Then
  For i = 1 To iSleepTimes
    Sleep (SleepyTime)      'Sleep at intervals of SleepyTime
    dNow = Timer
    If dNow > (dLastDoevents + (DoEventsRate / 1000)) Or dLastDoevents = 0 Or dLastDoevents > dNow Then
      DoEvents              'DoEvents if it's been long enough according to the DoeventsRate
      dLastDoevents = Timer
    End If
  Next i
End If

If msLeftOver > 0 Then
  Sleep (msLeftOver)        'Sleep for the remainder of milliseconds if needed (ie WaitFor 5)
  dNow = Timer
  If dNow > (dLastDoevents + (DoEventsRate / 1000)) Or dLastDoevents = 0 Or dLastDoevents > dNow Then
    DoEvents                'DoEvents if it's been long enough according to the DoeventsRate
    dLastDoevents = Timer
  End If
End If

1 个答案:

答案 0 :(得分:1)

在调试模式下,Visual Basic 6 IDE无法编译为本机代码(它解释P代码),因此您的代码行为与从exe运行时崩溃的行为不同。您可以生成使用P-Code的.exe,但不建议这样做。 (它有点减慢执行速度,但似乎你想减慢速度)。

正如评论部分所述,WaitFor不是VB函数,而且VB6因其简单的多线程功能而闻名。很难从这里找出它崩溃的原因,但已知DoEvents会导致崩溃due to stack overflows

由于您可以访问这两个代码,我建议修改它们以提供基于事件的机制。如果您不使用COM或不想引发COM事件,您还可以使用其他通信通道(如命名管道)告诉VB6工作已完成。