views:

158

answers:

2

Is it possible to have:

  1. A pure abstract class (basically an interface) in (unmanaged) C++
  2. Have managed implementations of this class in <insert .net language of your choice>
  3. Consume these managed implementations from (unmanaged) C++

Using SWIG or some C++/CLI glue?

+1  A: 

You can mostly always write custom C++/CLI glue to wrap managed objects in unmanaged wrappers or unmanaged objects in managed wrappers. If you don't want to go with this approach, you can also leverage COM and "COM/.NET interop". In other words, you can declare your interface in a COM .idl file; once you've done this, you should be able to both consume (and implement) the interface in both unmanaged and managed code (C++, C++/CLI, C#, etc.).

In C++ (unmanaged or otherwise), you can #import the idl or else #include the header file(s) that your compiler of choice generates after "compiling" the idl through midl.exe. For C#, you can either write some managed APIs in C++/CLI to wrap the COM interfaces or you can use tlbimp.exe to auto-magically generate a managed assembly from the COM type library (.tlb) that midl generates. This "interop assembly" can be directly referenced by any regular old managed assembly.

(This might all seem a bit cryptic or magical if you're not familiar with COM or COM/.NET interop; for more information on how to expose COM components to .NET, here's some background material on MSDN to start you off.)

Once you've successfully exposed the COM component(s) in question to .NET, implementing one of the exported COM interfaces in .NET should be as simple as defining a new class in C# or C++/CLI that inherits from the interface in question.

As for requirement #3... how you go about it really depends on the broader problem you're trying to solve. Once you somehow pass a reference to the managed object (which implements the COM interface) to native code, that code can really just use the object as if it's a native COM object; it can--for the most part--remain blissfully unaware of which language was used to implement the required COM interfaces. If you provide additional details about the context of your problem, we might be able to provide additional pointers on how to make this happen.

Reuben
+1  A: 

SWIG is the tool you want to use here. Specifically, use SWIG directors. From the online documentation:

The SWIG directors feature adds extra code to the generated C# proxy classes that enable these classes to be used in cross-language polymorphism. Essentially, it enables unmanaged C++ code to call back into managed code for virtual methods so that a C# class can derive from a wrapped C++ class.

It's pretty simple, although the devil's in the details. Be very careful about object lifetime - you are dealing with two different memory management approaches, and if you're not careful it's easy to end up with invalid pointers. But that's a whole other story;)

Gene