managed/unmanaged interop critique ...

V

Vijay

Hi,

I am faced with the following common managed/unmanaged C++ interop
problem:

- I have a .NET form that acts as a front end GUI to a processing
engine in the background. The processing engine runs as a thread that
is managed by the front-end form class.
- The processing engine must have a callback mechanism to update the
form about progress, and to send status messages that will be displayed
by the GUI.

I am looking for the *simplest* solution that involves least changes to
the processing engine code and doesn't involve writing wrappers for
everything. Based on reading previous posts from this newsgroup, I
ended up with the following pattern:

// Form.h

class Form
{
// controls.

// event handlers.
void btnStart_Click(...);

// GUI status update functions.
void updateStatus(...);

};

---------
// Form.cpp

// the engine object - global variable :-(
Engine myEngine;

// form function implemetations.
void run_engine()
{
try
{
// ... setup the engine ...
myEngine.set_listener(this);

myEngine.process();

// ... cleanup the engine ...
}
catch(/* any exception thrown by Engine */)
{
// exception handler code
}
};


---------
// Engine.h
#include <vcclr.h>

public __gc class Form;

class Engine
{
gcroot<Form *> _pListener;

// engine related variables.

public:

void set_listener(gcroot<Form *> pListener);
// engine related member functions.


};

--------
// Engine.cpp

#include "Engine.h"
#include "Form.h"

#define STATUS(x) {/*format the message*/;_pListener->updateStatus();}
void Engine::process()
{
// processing code.
STATUS(("Running test %d of %d.", ...));
// processing code.
}

The method is low-impact because the only changes I did to the Engine
source code were to add 3-4 lines to setup the listener inside the
class, and change the status "#define" to update the status in the
listener. The rest of the code remains untouched and no wrappers were
written.

But, I am unable to have a Engine object as a member variable of the
Form class because of the presence of <gcroot> in the Engine class. I
worked around it by instantiating Engine as a global variable (yuk !)
in Form.cpp, but it *works* so far.

I'd appreciate it if the .NET gurus in this group would make a
constructive critique of my pattern, and/or make any suggestions to
make it more elegant. Is it possible to follow the same pattern, but
avoid the global variable (or is wrappers the only way to go) ?

Thanks,
Vijay.
 
V

Vladimir Nesterovsky

I am faced with the following common managed/unmanaged C++ interop
problem:
...
But, I am unable to have a Engine object as a member variable of the
Form class because of the presence of <gcroot> in the Engine class. I
worked around it by instantiating Engine as a global variable (yuk !)
in Form.cpp, but it *works* so far.

And what's a problem with referring to Engine in Form class?
 
V

Vijay

I am getting compiler errors telling me that I cannot use declare an
Engine object as a member function of Form, because of the presence of
gcroot<> in the Engine class.

Thanks,
Vijay.

PS: I am a newbie to the .NET platform ...
 
V

Vladimir Nesterovsky

I am getting compiler errors telling me that I cannot use declare an
Engine object as a member function of Form, because of the presence of
gcroot<> in the Engine class.

Thanks,
Vijay.

PS: I am a newbie to the .NET platform ...

Can we see a strip of code that fails to compile?
 
V

Vijay

Oops ! I was mistaken. The reason the code did not compile was because
I had elements of the standard library (std::vector, specifically) as
members of engine. The precise error message I am getting is :

error C3633: cannot define 'engine' as a member of managed 'myForm'
because of the presence of destructor 'std::vector<_Ty>::~vector' on
class 'std::vector<_Ty>' with
[
_Ty=int
]
and
[
_Ty=int
]
and
[
_Ty=int
]
C:\Program Files\Microsoft Visual Studio .NET
2003\Vc7\include\vector(386) : see declaration of
'std::vector<_Ty>::~vector'
with
[
_Ty=int
]
and
[
_Ty=int
]

Sorry,
Vijay.
 
V

Vladimir Nesterovsky

Oops ! I was mistaken. The reason the code did not compile was because
I had elements of the standard library (std::vector, specifically) as
members of engine. The precise error message I am getting is :

error C3633: cannot define 'engine' as a member of managed 'myForm'
because of the presence of destructor 'std::vector<_Ty>::~vector' on
class 'std::vector<_Ty>' with


You can define engine as a pointer to Engine in your managed class.
Don't forget to create it in constructor and free it in Dispose of the form.
 
V

Vijay

Thanks very much for the suggestion !

-Vijay.

Vladimir said:
You can define engine as a pointer to Engine in your managed class.
Don't forget to create it in constructor and free it in Dispose of the form.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top