wrapping an abstract base class

L

Lee Crabtree

More fun wrapping unmanaged code...

I have a class heirarchy that I need to expose to C#, so I need to wrap all
the classes. That's not a big deal, except for the base class, which is
abstract. Since you can't instantiate an abstract class, I can't use a
pointer to the unmanaged type to handle the function calls.

Is there a good way to do this?

Lee
 
B

Brian Muth

Since you can't instantiate an abstract class, it makes no sense to wrap it
(expose it to C#) since you can't use it anyway. So why do you feel
compelled to wrap it?

Brian
 
L

Lee Crabtree

That's an excellent point that hit me two minutes after I posted my message.
I guess I've just done so much wrapping in the last week or so that I've got
wrap-happy.

Lee
 
O

Olaf Baeyens

I have a class heirarchy that I need to expose to C#, so I need to wrap
all
the classes. That's not a big deal, except for the base class, which is
abstract. Since you can't instantiate an abstract class, I can't use a
pointer to the unmanaged type to handle the function calls.

Abstract classes are half-built classes.
You must inherit from it and define the missing functionality.
Your compiler will tell you what methods needs to be created that are
incomplete in the abstract class.
 
L

Lee Crabtree

I've found at least one reason why wrapping an abstract base class makes
sense.

Say the base class for several different other classes contains a lot of
functions that are inherited without being reimplemented. Without wrapping
the base class, you would have to wrap those functions in every single
inherited class. That seems like a lot of unnecessary work.

In C++, an abstract class can still have function definitions that actually
perform operations. Redefining those functions in every single derived
class is definitely unneeded work.

Any ideas?

Lee
 
T

Tamas Demjen

Say the base class for several different other classes contains a lot of
functions that are inherited without being reimplemented. Without wrapping
the base class, you would have to wrap those functions in every single
inherited class. That seems like a lot of unnecessary work.

In that case consider my example. I introduced a method called
GetUnmanaged(), which is supposed to return the underlying native
implementation. In the abstract base, you don't know that pointer yet,
but in the derived classes you can just implement GetUnmanaged, which is
a trivial implementation. Can you live with that? ExecuteTwice did not
have to be duplicated in the derived classes.

Note that I used the new C++/CLI syntax. If you're using VC++ 2003,
you'll have to edit my code, but the concept is the same. This should
get you started.

Tom

// Wrap1.cpp : main project file.
// Output of the application is:
// UnmanagedDerived::Execute
// UnmanagedDerived::Execute

#include "stdafx.h"
#include <iostream>

using namespace System;

// native:

class UnmanagedBase
{
public:
virtual ~UnmanagedBase() { }
virtual void Execute() = 0;
void ExecuteTwice() { Execute(); Execute(); }
};

class UnmanagedDerived : public UnmanagedBase
{
public:
virtual void Execute() { std::cout << "UnmanagedDerived::Execute\n";
}
};

// managed:

ref class ManagedBased abstract
{
public:
virtual void Execute() { GetUnmanaged()->Execute(); }
void ExecuteTwice() { GetUnmanaged()->ExecuteTwice(); }
protected:
virtual UnmanagedBase* GetUnmanaged() = 0;
};

ref class ManagedDerived : public ManagedBased
{
public:
ManagedDerived() : ptr(new UnmanagedDerived) { }
~ManagedDerived() { delete ptr; }
protected:
virtual UnmanagedBase* GetUnmanaged() override { return ptr; }
private:
UnmanagedDerived* ptr;
};

int main(array<System::String ^> ^args)
{
ManagedDerived md;
md.ExecuteTwice();
return 0;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top