translating more stuff from C

  • Thread starter Thread starter Lance
  • Start date Start date
L

Lance

Hi all,

I'm not even really sure how to phrase this question, so please forgive me.

Given an entry in a C++ header file like such:

/////
// Callback for displaying error and warning messages.
typedef void (_stdcall *GM_MessageCallbackFunc)
(
const char* aMessageText
);
/////

and function in the C++ header file like such:

/////
GM_DLL_EXPORTED void __stdcall GM_SetMessageCallback
(
GM_MessageCallbackFunc aCallbackFunc
);
/////

how do I translate this to VB2005 and then actually use it?

Lance
 
how do I translate this to VB2005 and then actually use it?

Try this:

Delegate Sub GM_MessageCallbackFunc(aMessageText As String)

Declare Sub GM_SetMessageCallback Lib "your.dll" (aCallbackFunc As
GM_MessageCallbackFunc)


Mattias
 
Mattias,

This will take a while me to properly implement, given that I know very little about
delegates. According to the comments in the C++ header file, this is supposed to:

// Sets the function to call to display error and warning messages generated
// during operations. If a message callback is provided, a message
// dialog will not be shown, instead the callback function will be called
// with the error or warning message that would have been displayed.
 
Ok, I've placed

/////
Public Delegate Sub GM_MessageCallbackFunc(ByVal aMessageText As String)

Public Declare Sub GM_SetMessageCallback Lib "GlobalMapperInterface" _
( _
ByVal aCallbackFunc As GM_MessageCallbackFunc _
)
/////

into a module. On a Form I've placed

/////
Private Sub HandleLoadError(ByVal sError As String)
Debug.Print(sError)
End Sub

Private Sub Load()
Dim MessageDelegate As GM_MessageCallbackFunc
MessageDelegate = AddressOf HandleLoadError
(...Attempt Data Loading...)
End Sub
/////

but my handling sub is never called. It should be, because unmanaged DLL that I'm making
calls to displays it's Load Error dialog box - which is what the Sub above is supposed to
supress and let the client handle instead. What have I done incorrectly?

Lance
 
Got it! I added

/////
GM_SetMessageCallback(MessageDelegate)
/////

after

/////
Dim MessageDelegate As GM_MessageCallbackFunc
MessageDelegate = AddressOf HandleLoadError
/////

and it worked.

Thanks Mattias!
Lance


Lance said:
Ok, I've placed

/////
Public Delegate Sub GM_MessageCallbackFunc(ByVal aMessageText As String)

Public Declare Sub GM_SetMessageCallback Lib "GlobalMapperInterface" _
( _
ByVal aCallbackFunc As GM_MessageCallbackFunc _
)
/////

into a module. On a Form I've placed

/////
Private Sub HandleLoadError(ByVal sError As String)
Debug.Print(sError)
End Sub

Private Sub Load()
Dim MessageDelegate As GM_MessageCallbackFunc
MessageDelegate = AddressOf HandleLoadError
(...Attempt Data Loading...)
End Sub
/////

but my handling sub is never called. It should be, because unmanaged DLL that I'm
making calls to displays it's Load Error dialog box - which is what the Sub above is
supposed to supress and let the client handle instead. What have I done incorrectly?

Lance
 
Just make sure you keep a live reference to the delegate as long as
the callback is needed. If you let the delegate get garbage collected,
bad things will happen.


Mattias
 
If all the code requiring the reference to the delegate is in the same procedure as the
delegate itself then it shouldn't be collected too early, right?

Lance
 
If all the code requiring the reference to the delegate is in the same procedure as the
delegate itself then it shouldn't be collected too early, right?

It could be. The garbage collector can be pretty aggressive and clean
up objects even before the method in which they are created returns.

Any time you're dealing with asynchronous callbacks where the actual
calls back to your code happen after the P/Invoke call (to
GM_SetMessageCallback in this case) returns, you have to be careful to
keep the delegate alive.


Mattias
 
Hm, ok....how would you suggest doing that?


Mattias Sjögren said:
It could be. The garbage collector can be pretty aggressive and clean
up objects even before the method in which they are created returns.

Any time you're dealing with asynchronous callbacks where the actual
calls back to your code happen after the P/Invoke call (to
GM_SetMessageCallback in this case) returns, you have to be careful to
keep the delegate alive.


Mattias
 
Back
Top