translating more stuff from C

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
 
M

Mattias Sjögren

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
 
L

Lance

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.
 
L

Lance

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
 
L

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
 
M

Mattias Sjögren

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
 
L

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?

Lance
 
M

Mattias Sjögren

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
 
L

Lance

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top