This is my article 3 with the Native Event. The first article made a brief introduction to Native Event. The second report is a bug (MSVC Team said this is a known bug, but still exists in VC8EXPRESS). This article we look at how Native Event is implemented, and try to solve the bug we encounter.
From VC7 (Microsoft Visual C .NET (2002)), MSVC provides the Native Event mechanism, trying to introduce a way to implement Delegate in C . A total of 4 extensions are provided: __ event (definition an event), __ raise (trigger an event), __ hook (connect a member function to Event), __ unhook (remove the specified function), and two roles on the class Features: Event_source (an event source), event_receiver (an event recipient).
Why is it possible to have a very ugly key? What kind of code is these critical children?
You can use the following compile command to compile my code in the second article.
CL / FX / FAS NATIVE_EVENT.CPP
The / FX compilation option generates a native_event.mrg.cpp, which is the source code generated after the MSVC compiler is expanded in the feature. / FAS Compile Option Generates the corresponding assembly code.
We look at native_event.mrg.cpp is enough to understand Native Event's implementation method.
__event criminals are unfolded into an event function Links Pointer, a fictitious body, a template structure, 3 template functions, a member function named __removealleventhandlers, an Inline function with the same name with the Event name. There are 4 auxiliary structures in addition to this. It can be seen that the EVENT mechanism is a very similar macro definition implementation.
__hook The function pointer is added to the function chain through the __addeventhandler template function. __unhook remove function pointer from the list.
__Raise itself is not used. When actually called event functions, the function in the function chain list will be circulated. Object entity pointer (this) and member function pointer are stored in each node of the function linker. Member function pointer with VOID * pointer transition utilizes __eventinggetaddR this dexterous auxiliary class.
Although the code looks a bit chaos, it is not very long, it should be easy to understand.
I happened in the second article.
INT __ISEQUAL (void * p, void * pfn) {return ((t *) p == this-> p) && (_EventinggetAddr
It seems that a viable replacement is:
INT __ISEQUAL (Void * p, void * pfn) {return ((t *) p == this-> p) && pfn == __EventinggetAddr
The consequences resulting in this bug are: Native Event cannot be used in ATL / WTL. This makes this mechanism almost loses its meaning.
Warning: Be careful with Native Event.
Recommendation: Do not use Native Event before the MSVC is corrected.