views:

123

answers:

3

Hi,

I have a large application written in native C++. I also have a class in C# that I need to call.

If the C# class was static, then it would be trivial (there's lots of examples on the web) - just write the mixed C++/CLI wrapper, export the interfaces, and you're done.

However, the C# class is non-static, and can't be changed to static as it has an interface (the compiler will generate an error if you attempt to make the C# class static).

Has anyone run into this problem before - how do I export a non-static C# class to native C++?


Update 2010-10-08

Currently evaluating both COM and the source code for the C++/CLI wrapper class (thanks by Steve and Sergey).

+7  A: 

C++/CLI or COM interop work just as well with non-static classes as with static. Using C++/CLI you just reference your assembly that holds the non-static class and then you can use gcnew to obtain a reference to a new instance.

What makes you think that this is not possible with your non-static class?

EDIT: there is example code here.

using namespace System;

public ref class CSquare
{
private:
    double sd;

public:
    CSquare() : sd(0.00) {}
    CSquare(double side) : sd(side) { }
    ~CSquare() { }

    property double Side
    {
    double get() { return sd; }
    void set(double s)
    {
        if( s <= 0 )
        sd = 0.00;
        else
        sd = s;
    }
    }

    property double Perimeter { double get() { return sd * 4; } }
    property double Area { double get() { return sd * sd; } }
};

array<CSquare ^> ^ CreateSquares()
{
    array<CSquare ^> ^ sqrs = gcnew array<CSquare ^>(5);

    sqrs[0] = gcnew CSquare;
    sqrs[0]->Side = 5.62;
    sqrs[1] = gcnew CSquare;
    sqrs[1]->Side = 770.448;
    sqrs[2] = gcnew CSquare;
    sqrs[2]->Side = 2442.08;
    sqrs[3] = gcnew CSquare;
    sqrs[3]->Side = 82.304;
    sqrs[4] = gcnew CSquare;
    sqrs[4]->Side = 640.1115;

    return sqrs;
}
Steve Townsend
I decided to go with COM. Our of interest, do you know of any examples of a C++/CLI wrapper instantiating a non-static class in C#? I couldn't get around the compiler errors, no matter what I tried, and none of the examples of the web were for anything other than a static class.
Gravitas
@Gravitas - see edit
Steve Townsend
Excellent, thanks. For completeness, the source code you reference is designed for MSVS 2003, and won't work unless its upgraded to MSVS 2005, instructions and updated source are at http://msdn.microsoft.com/en-us/magazine/cc163602.aspx (thanks @Sergey).
Gravitas
+3  A: 

Two options come to mind.

  1. Expose the class as a COM object and use it as a COM object from C++.
  2. Create a static C# class that exposes an interface to interact with the non-static C# class.
Chris Taylor
I decided to go with COM, and it works perfectly. Thanks very much for your time in answering this question - much appreciated.
Gravitas
+1  A: 

I've investigated this topic couple of years ago: I want to use log4net and Npgsql libraries from native code that compiles even without /clr key.

The main idea behind this technique described by Paul DiLascia in his two remarkable articles:

Managed Code in Visual Studio 2005

Use Our ManWrap Library to Get the Best of .NET in Native C++ Code

The main idea in this solution that gcroot smart pointer and intptr_t have exactly the same representation in memory. And we creating a macro called GCROOT(T) that uses gcroot in Managed code and intptr_t in unmanaged. And that we create DLL with native interface and managed implementation and uses this dll from our native code.

It was pretty easy for me create some adapter for my managed classes and use them in native C++ world and compile my source code even without /clr key.

Sergey Teplyakov
I had a look at the code you referenced, and it looks very easy to use: I'll implement both COM and the code above, and edit my original question to correct it. Many thanks!
Gravitas