[Mono-dev] sigc++ signal C# wraper

Jonathan Pryor jonpryor at vt.edu
Tue Oct 30 16:49:50 EDT 2007

On Tue, 2007-10-30 at 17:33 -0300, buhochileno at gmail.com wrote:
> I only have now a little problem, but I'm sure that is my stupidity, I 
> add to the C# example code that you send me a delegate and a event , to 
> allow to other C# class to asociate  method to this event in a 
> traditional .Net/mono way, something like this (only for test):
> ...
> [DllImport ("/usr/local/lib/devel/libaliendetector.so")]
>     private static extern void AlienDetector_AddSignalDetected (IntPtr 
> detector, SignalDetectedHandler h);
> ...
> public delegate void SignalDetectedHandlerM (); //I define this to not 
> use the delegate used in the 

There's no need to use a new delegate type here.  It only increases
overhead (more types to JIT) for no obvious gain.

> //DllImport...AlienDetector_AddSignalDetected...
>     public static event SignalDetectedHandlerM SignalDetected;
> ...
> and then in the "MyHandler" method (the method executed by the unmanaged 
> code) I add this:
>     public static void MyHandler ()
>     {
>         Console.WriteLine ("Managed Code Invoked!"); //this work prefectly
>         Demo.SignalDetected(); //traditional .net/mono event trigger, 
> dont' work
>     }
> ...allways I get a:
> Unhandled Exception: System.NullReferenceException: Object reference not 
> set to an instance of an object

The problem is a C# language "feature" that trips up many people: if
there are no subscribers to an event, then the event is "null".
Consequently, you need to guard against a null event:

	SignalDetectedHandler h = Demo.SignalDetected;
	if (h != null)
		h ();

Yes, you should have a temporary `h' variable, as done above, for thread
safety reasons.  (Assignment is atomic.  If you instead did
"if(Demo.SignalDetected != null) Demo.SignalDetected ();", then
Demo.SignalDetected could be changed by another thread in between the
`if' and the Demo.SignalDetected() invocation.  Using `h' is safe,
because assignment is atomic, and if Demo.SignalDetected is changed
between `if (h != null)' and `h ();', it won't matter, as `h' itself
will be unchanged.)

 - Jon

More information about the Mono-devel-list mailing list