This article demonstrates something I should have tested years ago. I've been wondering about the power and limitations of the Microsoft C++ CLI for years, nearly always choosing C# for my .NET development needs.
What if it is possible to combine a powerful C++ Framework like ACE with .NET Microsoft C++ CLI and mixed mode programming? Turns out it works quite well.
The simple purpose of this program will be to execute code in a native thread, and return a result to the calling managed code.
Compile ACE as described by the included documentation. I'll assume you know how to set up the include and library paths for the project, and how to set up a mixed mode C++ CLI project.
Follow this link to download ACE.
What really surprised me was how easy it was – it probably shouldn’t, but it did.
First, we create a Visual C++ Windows Forms Application.
We are going to pull in a few header files from ACE, so open stdafx.h and add the following:
#include <sdkddkver.h />
#pragma managed(push,off) and
#pragma managed(pop) turns off and on managed code compilation respectively, enabling unmanaged code compilation.
In ACEDotNetDemo.cpp which contains our C++ CLI main method, we add the following just before our
This lets the linker know that we want to link against "ace.lib" or "aced.lib" in release or debug builds respectively.
main method is fairly standard, we only call
ACE::fini() to initialize and finalize the framework.
int main(array<:string> ^args)
int result = ACE::init();
if(result >= 0)
In ACEDotNetDemoTask.hpp, we declare a very simple class
ACEDotNetDemoTask derived from
ACE_Task_Base. This is our thread implementation, and the
svc method is executed in another thread.
typedef ACE_Future<int> IntFuture;
class ACEDotNetDemoTask :
virtual int svc (void);
int enqueue (ACE_Method_Request *request);
typedef ACE_Singleton<ACEDotNetDemoTask, ACE_Null_Mutex>
class ExitMethodRequest :
virtual int call (void)
int result = -1;
ACE_Singleton to declare a singleton,
ACEDOTNETDEMOTASK, for our
ACEDotNetDemoTask.cpp contains the implementation of
svc method dequeues method requests from the activation queue, and calls the
call method of the dequeued request until the
call method returns
-1, quite similar to a standard windows message loop.
int ACEDotNetDemoTask::svc (void)
request (this->activation_queue_.dequeue ());
if (request->call () == -1)
enqueue method enqueues request into the activation queue, for servicing by the
int ACEDotNetDemoTask::enqueue (ACE_Method_Request *request)
return this->activation_queue_.enqueue (request);
call_exit enqueues an
ExitMethodRequest to the activation queue, and returns an
IntFuture that allows the caller to get the result from the unmanaged thread.
ExitMethodRequest *request = new ExitMethodRequest(result);
That takes care of our unmanaged thread implementation based on
Interacting with the unmanaged thread from managed C++ CLI code is as you can see really, really simple.
virtual void OnShown(EventArgs^ e) override
virtual void OnFormClosing(FormClosingEventArgs^ e) override
IntFuture futureResult = ACEDOTNETDEMOTASK::instance()->call_exit();
int result = 0;
No doubt, many of you already know that integrating managed and unmanaged code using mixed mode C++ CLI works amazingly well. But I guess there are many like me who thought this a tantalizing, even probable, idea – but just never got around to verifying it.
What I’ve implemented is a simple active object in unmanaged code; and interacted with it successfully from managed code.
So in the hope that some of you may find it useful, I wrote this little article demonstrating that it actually works very well.
- 6th of January, 2011 - Initial posting