1

Part of a Visual Basic program is being moved to .NET dll.

Parameter call can be passed successfully & everything run fine.

How can I pass a callback function of VB6 for .NET to call after a long running async task?

In .NET

Public Delegate Function VBCallBackFunc() As Integer

Public Function DoSomething(a As String, b As String, c As String, _
parent As IntPtr, Optional ByVal CallbackAddr As VBCallBackFunc = Nothing) As Boolean Implements _DotNetLib.DoSomething

VB6

result = DotNetLib.DoSomething(strA, strB, strC, Me.hwnd, AddressOf DotNetCallback)

Public Function DotNetCallback() As Long
    MsgBox ("Callback")
End Function

In object browser of VB:

Function DoSomething(strA As String, strB As String, strC As String,
 parent As Long, [CallbackAddr As VBCallBackFunc]) As Boolean

Member of DotNetLib

But it said "Invalid use of AddressOf operator" ???

BigBen
  • 46,229
  • 7
  • 24
  • 40
HardcoreGamer
  • 1,151
  • 1
  • 16
  • 24

1 Answers1

3

The comments related to using Events are a good option, but I tend to use interfaces more, so here is a solution for that.

(Free-hand code, you will need to syntax check and the names can be cleaned up, they are just for illustration purposes)

In .NET:

Create an COM exposed interface for your callback:

Public Interface IVBCallBack
   Public Function VBCallBackFunc() As Integer
End Interface

Change your DoSomething be like this:

Public Function DoSomething(a As String, b As String, c As String, parent As IntPtr, ByVal CallbackAddr As IVBCallBack) As Boolean

In VB6:

result = DotNetLib.DoSomething(strA, strB, strC, Me.hwnd, Me)

(And you will need your class, control, or form to Implements IVBCallBack)

Public Function IVBCallBack_VBCallBackFunc() As Long
    MsgBox ("Callback")
End Function

Be sure to have a method on the .NET side to clean up and release all your references since .NET is holding a reference to the VB6 object.

One other thing to note. DO NOT CALL BACK INTO VB6 ON ANY THREAD OTHER THAN THE MAIN UI THREAD!

tcarvin
  • 10,715
  • 3
  • 31
  • 52
  • Plus one - AFAICR using events in COM/.Net interop is a bit flaky so I would choose this option – MarkJ Jun 12 '20 at 13:42
  • Question was for "For .NET to call after a long running async task". Events should shield the developer from threading or dangling cross referencing issues (provided VB code pumps windows messages) – Simon Mourier Jun 12 '20 at 14:58
  • Events can be called on other threads, but for sure, as I opened with, Events are a good option. I have hit some issues with them in the past that I don't recall the specifics of (VB6 is getting old now) so I ended up going with an Interface approach and never looked back. – tcarvin Jun 12 '20 at 17:35
  • Interestingly, I found this post (https://stackoverflow.com/questions/18224220/com-interop-and-thread-synchronization) that indicates that perhaps my warning was premature and that the magic of COM interop will take care of the threading. YMMV – tcarvin Jun 12 '20 at 18:11
  • This works well. After VB6 Implements DotNetLib.IVBCallBack, function is now called successfully from .NET in main thread using Invoke. Nicely done, many thanks! – HardcoreGamer Jun 15 '20 at 02:38