【问题标题】:VB6 AddressOf and Callbacks in VS 2008VS 2008 中的 VB6 AddressOf 和回调
【发布时间】:2017-12-19 01:02:48
【问题描述】:

大家好,我正在尝试通过其自动 VB6 代码转换器将一些 VB6 代码转换为 VS 2008。大多数都很好,但也有一些需要改进。

一个说修饰是这段代码:

InitializeGrCap = GrCapInitialize(AddressOf GrCapStatusEventHandler)

GrCapInitialize 是这样的:

Public Declare Function GrCapInitialize Lib "GrFinger.dll" Alias "_GrCapInitialize@4" (ByVal StatusEventHandler As Integer) As Integer

GrCapStatusEventHandler 是:

Public Sub GrCapStatusEventHandler(ByVal pidSensor As Integer, ByVal eventRaised As Integer)
    While fireStatus = True
        System.Windows.Forms.Application.DoEvents()
    End While

    myPIdSensor = pidSensor
    myEventRaised = eventRaised     
    fireStatus = True

    While fireStatus = True
        System.Windows.Forms.Application.DoEvents()
    End While
End Sub

我不确定如何重写它以解决以下问题:

错误 44 'AddressOf' 表达式无法转换为 'Integer',因为 'Integer' 不是委托类型。

第二个说的修饰是这段代码:

GrCapStartCapture(myIdSensor, AddressOf GrCapFingerEventHandler, AddressOf GrCapImageEventHandler)

同样,AddressOf ... 是这个错误:

GrCapFingerEventHandler

Public Sub GrCapFingerEventHandler(ByVal pidSensor As Integer, ByVal eventRaised As Integer)
    While fireFinger = True
        System.Windows.Forms.Application.DoEvents()
    End While

    myPIdSensor = pidSensor
    myEventRaised = eventRaised
    fireFinger = True

    While fireFinger = True
        System.Windows.Forms.Application.DoEvents()
    End While
End Sub

还有GrCapImageEventHandler

Public Sub GrCapImageEventHandler(ByVal pidSensor As Integer, ByVal width As Integer, ByVal height As Integer, ByVal pRawImage As Integer, ByVal res As Integer)
    While fireImage = True
        System.Windows.Forms.Application.DoEvents()
    End While

    myPIdSensor = pidSensor
    myWidth = width
    myHeight = height
    myRes = res
    myRawImage = pRawImage
    fireImage = True

    While fireImage = True
        System.Windows.Forms.Application.DoEvents()
    End While
End Sub

同样,错误是:

错误 44 'AddressOf' 表达式无法转换为 'Integer',因为 'Integer' 不是委托类型。

谁能帮我将这两个代码区域转换为 .net?

【问题讨论】:

    标签: vb.net vb6 addressof


    【解决方案1】:

    在 VB6 中,传递给非托管函数的 Integer 将是函数指针。 VB.NET 不做函数指针。 .NET 使用委托代替,委托是指方法的对象。这意味着您需要一个具有与托管方法匹配的签名的委托类型,然后您可以将非托管函数的参数声明为该类型,并在调用该函数时传递该类型的实例。您可以声明自己的委托类型,例如

    Public Delegate Sub GrCapStatusCallback(ByVal pidSensor As Integer, ByVal eventRaised As Integer)
    

    声明您的外部函数以使用该类型:

    Public Declare Function GrCapInitialize Lib "GrFinger.dll" Alias "_GrCapInitialize@4" (ByVal StatusEventHandler As GrCapStatusCallback) As Integer
    

    然后您的调用应该按原样工作,或者您可以显式创建一个委托实例:

    InitializeGrCap = GrCapInitialize(New GrCapStatusCallback(AddressOf GrCapStatusEventHandler))
    

    或者,您可以使用现有的 ActionFunc 代表,它们分别用于 SubsFunctions,可以支持 0 到 16 个参数:

    Public Declare Function GrCapInitialize Lib "GrFinger.dll" Alias "_GrCapInitialize@4" (ByVal StatusEventHandler As Action(Of Integer, Integer)) As Integer
    

    【讨论】:

    • 感谢您的回复,JM。但是,将其更改为 InitializeGrCap = GrCapInitialize(New GrCapStatusCallback(AddressOf GrCapStatusEventHandler)) 时我仍然遇到相同的错误,错误是 Error 1 Value of type 'GrFingerSampleVB6.Callbacks.GrCapStatusCallback' cannot be转换为“整数”。
    • 那么您没有更改非托管方法的声明,我在回答中特别提到了这一点。
    • 抱歉错过了那个。 OP中说明的第二期怎么样?
    • 同一个问题,用同样的步骤解决。
    • 虽然它的机制是正确的,但如果在 GrCapInitialize 方法调用中实例化的委托被垃圾回收,它的实现可能会导致 空引用异常。您需要维护对委托的引用以防止它被收集。有关此问题的讨论,请参阅 Asynchronous operations, pinning。在文章中搜索:“应用程序负责以某种方式延长委托的生命周期,直到不再有来自非托管代码的调用。”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多