Click here to Skip to main content
16,021,823 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
In C#, one can define an event delegate & handler thusly:
C#
class SomeClass
{
    public delegate void SomeEventHandler(object sender, int n);
    public event SomeEventHandler SomeEvent;

    public void RaiseEvent(int n)
    {
        if (SomeEvent != null)
            SomeEvent(this, n);
    }

}


then some consuming code could do this:
C#
SomeClass sc = new SomeClass();
sc.SomeEvent += new SomeClass.SomeEventHandler(sc_OnSomeEvent);
sc.RaiseEvent(2);

which would cause sc_OnSomeEvent() to be called with 2.

I'm having some trouble writing this in C++/CLI.
Here's what I have so far:
C#
public ref class CppCliClass
{
public:
    delegate void CppCliEventHandler(int n);
    event CppCliEventHandler^ OnCppCliEvent;

    void RaiseCppCliEvent(int n)
}


but I'm having trouble writing RaiseCppCliEvent().
Based on the C# syntax, I'd expect it to be coded like this:
C#
void CppCliClass::RaiseCppCliEvent(int n)
{
    if(OnCppCliEvent != nullptr)
        OnCppCliEvent(this, n)
}


but I get these compiler errors:
error C3918: usage requires 'CppCliClass::OnCppCliEvent' to be a data member
error C2660: 'CppCliClass::OnCppCliEvent::raise' : function does not take 2 arguments


Any suggestions on the correct C++/CLI calling syntax for OnCppCliEvent() from within RaiseCppCliEvent() ?
Posted
Comments
Simon Bang Terkildsen 22-Oct-11 16:12pm    
For the comment you posted that I guess you subsequently deleted. My answer is perfectly valid, it just doesn't cover the issue mentioned by SA.
So what you were trying not to be, you turn out to be.
Member 11057470 18-Sep-14 6:02am    
Can i use C++ objects and call their methods in C++/CLI code.

Yes, this is well-known problem — C++/CLI is very different. Solution is also well-known, but it might look very unusual: not only you are not allowed to do the check like if(OnCppCliEvent != nullptr), you also never need it!

In other words, just delete this check — the code will work correctly. If event handler is not added, the code invoking event will not be called, automatically. Hard to believe, but try it!

Here is the simplest usage pattern:

C++
ref class EventSample {
public:
    event System::EventHandler^ SomeEvent;
private:
    void FireEvent() {
        //no check-up for nullptr SomeEvent is required here
        //event instance is not a method, if it won't be called in the line above it it's null:
        SomeEvent(this, gcnew System::EventArgs());
    }
    //...
};


Event instance is not a method, it is a instance of some (hidden, auto-emitted per each event argument class used) class which has an invocation list in it, event per se is not called, handlers stored in the invocation lists are. I explained it in my article: Dynamic Method Dispatcher[^]. Sorry, the article in C# where the check for null is actually allowed and needed, but it is not so in C++/CLI.

—SA
 
Share this answer
 
v3
Comments
DLChambers 22-Oct-11 15:30pm    
Thanks for the answer! To keep moving while awaiting help, I coded it w/o the null check, but it felt strange. On your suggestion, I did try invoking w/o any handlers, and it didn't throw an exception, so I guess it's not needed :)
Sergey Alexandrovich Kryukov 22-Oct-11 21:32pm    
You are welcome.
That was wise of you to perform this test. All correct.

Good luck, call again,
--SA
CppCliEventHandler only takes an integer as parameter update it to reflect your new design.
E.g.
C++
delegate void CppCliEventHandler(CppCliClass^ sender, int n);
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 21-Oct-11 22:45pm    
Simon, I think you miss the essence of the problem: the check of delegate instance for null is not allowed in C++/CLI. This is very interesting problem, the solution is well-known (but not so popular, because there are not so many good C++/CLI developers).

Please see my solution -- it addresses the problem and is interesting to get familiar with.
--SA
Simon Bang Terkildsen 22-Oct-11 9:56am    
Ah ok, I've never used C++/CLI other than when I've replied to questions here.
However the delegate the OP defines still has to be defined as I've defined it or he will still get the posted exception.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900