views:

237

answers:

1

hello, i have a solution, which has a C++ project and a C# project. the C++ project defines a class, which i want to instantiate in C# and call it's member functions. so far what i managed to do is to instantiate the class:

CFoo Bar = new CFoo();

but when i try to call a function on it, the compiler says, it is not available.

also, when i inspect the object in the debugger, no members are shown.

what am i missing here?

thanks!

+5  A: 

You need to declare the class in C++/CLI as a ref class.

(Note that we're talking about C++/CLI, not C++. I assume you must have enabled the CLR in your C++ project or you wouldn't be able to get the new CFoo to work.)

Edit:

You don't need to convert all your old classes in to ref classes.

Suppose you have some old C++:

class FooUnmanaged
{
    int x;

    FooUnmanaged() : x(5) {}
};

Then you try to wrap it in a CLR class:

ref class FooManaged
{
    FooUnmanaged m;
};

As you've noticed, you get an error saying this isn't allowed. But try this:

ref class FooManaged
{
    FooUnmanaged *m;
};

That's perfectly OK. The compiler doesn't want to allocate an instance of an unmanaged object embedded inside an object on the managed heap, but it's quite happy to have a pointer, which it turns into System.IntPtr in the resulting IL.

This means that you have to make a decision about how to call delete. The most likely solution is:

ref class FooManaged
{
    FooUnmanaged *u;

public:
    FooManaged(FooUnmanaged *u_)
        : u(u_) { }

    ~FooManaged() { delete u; }
};

Just as it would be in any other C++ class. It's possible that C++/CLI will be able to do this translation for us automatically in some future version.

Note that the resulting IL is that the FooManaged class now implements IDisposable, and the destructor has been turned into a Dispose method. This allows .NET clients to properly deallocate it, e.g. in C#

using (var m = new FooManaged())
{

    // end of block: m will be disposed (and so FooUnmanaged will be deleted)
}
Daniel Earwicker
thanks, if i do this i get a lot of errors like: Error 1 error C2814: a native type cannot be nested within a managed type . i guess that means that i need to change the members to managed types. is there a way to avoid this?
clamp
That error message is slightly misleading, see my edit.
Daniel Earwicker