Click to See Complete Forum and Search --> : Delegate Proplem


dieucay555
August 3rd, 2009, 10:32 PM
I trying use 1 DLL write by C++ in project C# but i hava a proplem!
In C++, when i create 1 event, using callback.For example : create event MouseMove : create 1 procedure is void CALLBACK MouseMoveProc(), and to handle events that it uses CadOnEventMouseMove(MouseMoveProc);in the form CadOnEventMouseMove void CadOnEventMouseMove (
F_MOUSEMOVE pFunc / / pointer to event procedure
);

To subscribe to the events which, in C # you do the following:
1 declare delegate to take the place of cursor to the function:
public delegate void MouseDelegate(int hDwg, int Button, int Key, int Xwin, int Ywin, double Xdwg, double Ydwg, double Zdwg);

And then, create event :
CadOnEventMouseMove(new VeCAD.MouseDelegate(MouseMoveProc));

When compiled no error but a few seconds after the application is crash, and errors arising :
"A callback was made on a garbage collected delegate of type 'VeCad_CS1!VeCAD.MouseDelegate::Invoke'. This may cause application crashes, corruption and data loss. When passing delegates to unmanaged code, they must be kept alive by the managed application until it is guaranteed that they will never be called."

Please help me!

vcdebugger
August 4th, 2009, 12:23 AM
Sorry I could not clearly understand your english.
You mean to say you have written the handler in a c++ dll ? and trigerring the event happens in the C# application?

monalin
August 4th, 2009, 11:46 AM
Never seen this error before or tried to do what you're doing so i may not be that much help. You might try the following code though. Its possible that the GC doesn't like you instanciating a new object in the parameter of an unmanaged function. You might need to bring the

new VeCAD.MouseDelegate(MouseMoveProc)

into a different scope so the GarbageCollector doesn't flip out.

Heres the new code you can try


public delegate void MouseDelegate(int hDwg, int Button, int Key, int Xwin, int Ywin, double Xdwg, double Ydwg, double Zdwg);
public event MouseDelegate MouseMove;

MouseMove += new MouseDelegate(MouseMoveProc);
CadOnEventMouseMove(MouseMove);

JonnyPoet
August 4th, 2009, 04:53 PM
..."A callback was made on a garbage collected delegate of type 'VeCad_CS1!VeCAD.MouseDelegate::Invoke'. This may cause application crashes, corruption and data loss. When passing delegates to unmanaged code, they must be kept alive by the managed application until it is guaranteed that they will never be called."

This states that you have instantiated a delegate without having it alive after you created it. Because you created itin the method parameter you do not point to this delegate anywhere in your program. Understand: Your delegate points to a method But the delegate itself is not stored in any field of that class so it is created and when you are leaving the method where you created it, this delegate goes to garbage colection, because nothing points to it !!

private void AnyMethodSettingTheDelegate(){
// because you create it directly as the callback method parameter
// you have no chance to have the pointer to this delegate
// method stored anywhere in your class. So this runs out of
// scope instantly when the method is finished
CadOnEventMouseMove(new VeCAD.MouseDelegate(MouseMoveProc));
...
} // just when the method is finished the delegate is out of scope !!!
In the code shown by monalin

namespace VeCad{
// define the delegate
public delegate void MouseDelegate(int hDwg, int Button, int Key, int Xwin, int Ywin, double Xdwg, double Ydwg, double Zdwg);

public class VeCad{
// create a field in your class so you have the delegate living as long as this class lives
public event MouseDelegate MouseMove;
// in the code wherever it is needed maybe in the classes CTor or
// where you want to set the callback you initialize the delegate to this adress
MouseMove += new MouseDelegate(MouseMoveProc);
// and now you set it to your method that uses the callback
CadOnEventMouseMove(MouseMove);
This way your delegate lives as long as this class lives. Hope you get the difference why this is needed :wave: