Hello all,
Any help on this issue appreciated because I am getting a bit stuck! I am
using VS.NET 2003.
I have wrapped a multithreaded win32 dll using managed C++ and added a C#
interface, but am having trouble directing the events generated by the win32
dll to events declared in the managed C++ layer, which are in turn directed
to the GUI.
The win32 dll is setup with classes that start worker threads which call
virtual methods that map their events to the controlling program. The
controlling program derives from the class and implements the event methods.
Here is a stripped down base class:
// Compile as win32 dll project (native.dll)
class Cnative
{
public:
// ...
void start(); // Sets worker thread going and returns
void stop(); // Stops worker thread and cleans up
protected:
virtual void event(int iProgress); // Generated by worker thread
};
In the managed C++ wrapper class I have mapped the events by defining a
managed class, containing an unmanaged class derived from Cnative as shown
below. The unmanaged class derives from Cnative, implements the event
method, and attempts to invoke a delegate in the wrapper class.
// Compile into managed C++ dll (layer.dll)
namespace layer {
public __gc class MyEventInfo
{
public:
MyEventInfo(Int32 iProgress) : iProg(iProgress) { }
Int32 iProg;
};
public __delegate void MyEventHandler(MyEventInfo *info);
public __gc class Wrapper : public System::Windows::Forms::Control
{
Wrapper() { m_pDerived = new Derived(this); }
~Wrapper() { delete m_pDerived; }
void Start() { m_pDerived->start(); }
void Stop() { m_pDerived->stop(); }
__event MyEventHandler *OnEvent;
private:
__nogc class Derived : public Cnative
{
public:
Derived(Wrapper *p) : m_pWrapper(p) { }
virtual void event(int i)
{
Wrapper *p = m_pWrapper; // Helps with auto-complete
MyEventHandler *pDelegate = new MyEventHandler(p,
&Wrapper::raise_OnEvent);
Object *aArgs[] = new Object*[1];
aArgs[0] = new MyEventInfo(i);
p->BeginInvoke(pDelegate, aArgs);
}
private:
gcroot<Wrapper*> m_pWrapper;
};
Derived *m_pDerived;
};
} // end namespace layer
There are various bits of code I have ommitted here that are called to
initialise the CRT library etc. I have a GUI written in C# that makes use of
the layer.Wrapper class. I need events from the worker threads created by
the classes in native.dll to be displayed using the C# GUI.
What I have written compiles, but when the Wrapper::Start method is called
for a wrapper object i get the following error:
An unhandled exception of type 'System.MethodAccessException' occurred in
Unknown Module.
Additional information: layer.Wrapper.raise_OnError(System.String)
I have stepped through my code with the debugger and everything works as
expected except when trying to access the Wrapper class methods from the
Wrapper::Derived class.
1. Can anybody shed any light as to why this error is occuring?
2. Am I attempting to map the events generated by the worker threads created
by Cnative::run() (in native.dll) correctly? Is there a better method?
3. Does anybody know of any sample code on the net that maps events from
threads in a native win32 dll to objects in a derived class and from there
into .NET? I found pages dealing with callbacks, but all the examples were
in the context of the one thread (the GUI thread).
Thanks in advance,
Dave