3

Hey all I am trying to convert some VB6 code to VS 2008 via its automated VB6 code converter. Most does well but there are a few that need a touch up.

One said touch up is this piece of code:

InitializeGrCap = GrCapInitialize(AddressOf GrCapStatusEventHandler)

And the GrCapInitialize is this:

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

And GrCapStatusEventHandler is:

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

I am unsure how to go about re-writing that in order to fix the issue of:

Error 44 'AddressOf' expression cannot be converted to 'Integer' because 'Integer' is not a delegate type.

The second said touch up is this piece of code:

GrCapStartCapture(myIdSensor, AddressOf GrCapFingerEventHandler, AddressOf GrCapImageEventHandler)

And again, the AddressOf ... are the errors in this one:

The 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

And 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

And again, the error is:

Error 44 'AddressOf' expression cannot be converted to 'Integer' because 'Integer' is not a delegate type.

Can anyone help me with converting these 2 code areas over to .net?

StealthRT
  • 10,108
  • 40
  • 183
  • 342

1 Answers1

4

In VB6, that Integer that you passed to your unmanaged function would be a function pointer. VB.NET doesn't do function pointers. .NET uses delegates instead, which are objects that refer to methods. That means that you need a delegate type with a signature that matches your managed method and then you can declare your unmanaged function's parameter as that type and pass an instance of that type when you call that function. You can declare your own delegate type, e.g.

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

declare your external function to use that type:

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

and then the call you have should work as is or you can create a delegate instance explicitly:

InitializeGrCap = GrCapInitialize(New GrCapStatusCallback(AddressOf GrCapStatusEventHandler))

Alternatively, you can use the existing Action and Func delegates, which are for Subs and Functions respectively and can support from 0 to 16 parameters:

Public Declare Function GrCapInitialize Lib "GrFinger.dll" Alias "_GrCapInitialize@4" (ByVal StatusEventHandler As Action(Of Integer, Integer)) As Integer
jmcilhinney
  • 50,448
  • 5
  • 26
  • 46
  • Thanks for the reply, JM. However i still get the same error when changing it to **InitializeGrCap = GrCapInitialize(New GrCapStatusCallback(AddressOf GrCapStatusEventHandler))** with the error being **Error 1 Value of type 'GrFingerSampleVB6.Callbacks.GrCapStatusCallback' cannot be converted to 'Integer'.** – StealthRT Jul 14 '17 at 04:30
  • Then you haven't changed the declaration of your unmanaged method, which I specifically addressed in my answer. – jmcilhinney Jul 14 '17 at 04:35
  • Ah sorry missed that one. How about the 2nd issue stated in the OP? – StealthRT Jul 14 '17 at 04:37
  • It's the same issue so you solve it with the same steps. – jmcilhinney Jul 14 '17 at 04:55
  • But it doesnt call a **Declare Function**, it calls a sub function (GrCapFingerEventHandler & GrCapImageEventHandler). – StealthRT Jul 14 '17 at 14:23
  • It's exactly the same situation as the first so you perform exactly the same steps to fix it. Read what I posted and do what it says. You've already done it once so there's no reason that you can't do it again. Let me write it again, so you have no excuse: You can declare your own delegate type; declare your external function to use that type; create a delegate instance explicitly. `GrCapFingerEventHandler` and `GrCapImageEventHandler` are the callback methods that you need to declare delegate types for. `GrCapStartCapture` is the method whose signature must use those delegate types. – jmcilhinney Jul 14 '17 at 14:54
  • 1
    While the mechanics of this is correct, its implementation could lead to a _Null Reference Exception_ if the delegate that is instantiated in the `GrCapInitialize` method call is garbage collected. You need to maintain a reference to the delegate to prevent it from being collected. See [Asynchronous operations, pinning](https://blogs.msdn.microsoft.com/cbrumme/2003/05/06/asynchronous-operations-pinning/) for a discussion on this. Search the article for: "the application is responsible for somehow extending the lifetime of the delegate until no more calls will occur from unmanaged code.". – TnTinMn Jul 14 '17 at 16:42