By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,680 Members | 1,710 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,680 IT Pros & Developers. It's quick & easy.

managed/unmanaged interop critique ...

P: n/a
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 <gcrootin 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.

Sep 17 '06 #1
Share this Question
Share on Google+
6 Replies


P: n/a
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 <gcrootin 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?
Sep 18 '06 #2

P: n/a
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 ...
Vladimir Nesterovsky wrote:
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 <gcrootin 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?
Sep 18 '06 #3

P: n/a
>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?

--
Vladimir Nesterovsky
Sep 18 '06 #4

P: n/a
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.

Vladimir Nesterovsky wrote:
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?

--
Vladimir Nesterovsky
Sep 18 '06 #5

P: n/a
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.
--
Vladimir Nesterovsky
Sep 19 '06 #6

P: n/a
Thanks very much for the suggestion !

-Vijay.

Vladimir Nesterovsky wrote:
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.
--
Vladimir Nesterovsky
Sep 19 '06 #7

This discussion thread is closed

Replies have been disabled for this discussion.