Click here to Skip to main content
15,881,882 members
Please Sign up or sign in to vote.
3.00/5 (1 vote)
See more:
0down votefavorite





In my c# app I have a progressbar. C# app is calling a c++/cli dll which processes a number of files. As each file is processed in the dll I would like to track it's progress in the c# app. For this i need to raise an event in c++/cli and consume it in C#. From MSDN I gather I need in my c++/cli class the following:
C++
delegate void Del(int);
 event Del^ E;
 void fire(int i) {
     E(i);
  }


http://msdn.microsoft.com/en-us/library/vstudio/58cwt3zh.aspx[^]
In my c# app I have

C#
MW.Class1 oM = new MW.Class1();
           oM.E += ProgressBarChanged;

In MSDN the receiver of the event is in the same c++/cli project and it is shown how to raise the event. In my project, the c# app is to receive the event which should be raised in c++/cli after each file is processed. I've googled a lot too but have not been able to figure it out yet. So, my question is, how do I raise this event in c++/cli, ? Some code that shows the way to do it would be greatly appreciated. thanks!
Posted
Comments
Sergey Alexandrovich Kryukov 13-Jun-13 13:06pm    
This is not a complete code which would compile. You should wrap it in some type, because this is important to the matter.
—SA

1 solution

There is no a problem to invoke event between languages: practically, there is no a barrier. The problem is different: it's not possible to invoke any event instance from anywhere except its declaring type. You cannot even derive a class and do it in the derived class. This is one important limitation of the event instanced, compared with delegate instances. Think of it as the fool-proof feature, no real limitation: this is never actually needed and could otherwise lead to the possibility of abuse.

Now, in you case: if, for example, you declare your fire method and declaring type public, you will be able to fire your event E from another assembly. As simple as that.

Let me tell you that you are not using recommended pattern for delegate types to be used for events. It should be used on System.EvenArgs (or, more usually, the custom class derived from this class, let's call this class MyEventArgs) and the delegate type System.EventHandler (in case of System.EvenArgs) or System.EventHandler<MyEventArgs>. In particular, FxCop (read about it and use it, this is a useful thing) will give you appropriate warning.

—SA
 
Share this answer
 
v3
Comments
bonosa 13-Jun-13 14:04pm    
Thank you, Sergey. I want to fire the event as soon as one file is done processing in the c++-cli dll. I want to receive this notification in the c# world. CAn this be done? I tried to just add "fire(100)" to my code after the 100th file finishes processing in the dll but it does not compile. I think you are saying above in your response that I can only raise the event in the c# project's code, and not in the c++-cli dll.. But in the c# project I do not know when the 100th file has finished processing. That's the whole point. That info is what I am trying to get across from my dll to my c# where an instance of the c++-cli class is declared. Maybe it is not an event raise mechanism that will handle this transfer of info? But some other concept?
thanks
Sergey Alexandrovich Kryukov 13-Jun-13 14:12pm    
I already answered: it can be done, but never directly, explained how.

I was talking about two different assemblies, because Visual Studio does not allow multiple-language assembly (and also because it allows one module per assembly). So, C++ and C# are divided by a assembly boundary, which is not a problem as soon as his is the same process. One assembly references another one. It does not matter which one reference which one, and which assembly defines the type with the event instance. It also does not matter if one of the assemblies is the entry-point one (application), or not. For you, there is no a boundary between them; the access is defined by "public" I mentioned.

That's all what is involved. You should know how to create assemblies and how to reference an assembly. I would strongly advise you put all projects in one solution and reference not by "Browse", but by "Project" tab of the "Add Reference" VS window.

Anything else?

—SA
Sergey Alexandrovich Kryukov 13-Jun-13 14:29pm    
As to processing many files: you certainly need to use threads. How about that?
—SA
bonosa 13-Jun-13 15:58pm    
yes, I'm using a backgroundworker. Thanks Sergey.
bonosa 13-Jun-13 14:28pm    
thank you, Sergei for your time and input.

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