www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - D object model

One of the problems with wrapping C++ is wrapping multiple-inheritance
classes. You could simulate these with interfaces, e.g.:

interface IRoot { }
interface IBase1 : IRoot { }
interface IBase2 : IRoot { }
class Base1 : IBase1 { void* cppObj; }
class Base2 : IBase2 { void* cppObj; }
class MIClass : IBase1, IBase2 { void* cppObj; }

Now to define a function that can be called with an object instance of
any class in the tree, you can use:
void foo(IRoot obj) { }

Typically every wrapper D class will have an associated pointer to a
C++ object as a void* field (hence that cppObj field up there). This
is to allow invoking C++ library methods on the underlying C++ object,
e.g.:

class Base1 : IBase1
{
    void* cppObj;
    void invokeMethod(IBase1 objArg)
    {
        extern_c_invokeMethod(this.cppObj, objArg.getCppObj());
    }
}

The above allows invokeMethod to be called with any IBase1-inherited
class (IBase1 or MIClass). Note that changing "IBase1 objArg" to
"Base1 objArg" would mean the method can't be invoked with an MIClass
instance (but it would allow direct access to the .cppObj field).

The problem here is performance. Interfaces don't hold state, so
classes which inherit from interfaces have to implement a special
"getCppObj()" method which returns the cppObj field. That means
retrieving cppObj is a virtual call instead of a simple field lookup.

My question is: I I have the definition of *all* the D classes in the
library (+ I control how they're inherited since they're
autogenerated) is it possible to cheat and retrieve the .cppObj field
from an interface parameter without going through a virtual call?

Obviously this would be implementation-dependent, but remember that
all the wrapper D classes would only hold 1 field (cppObj), so I was
hoping using a hack would be somewhat reliable. Here's one way to
cheat:

http://dpaste.dzfl.pl/fd794170

That trick would only be used for the wrapper classes. What I don't
know is, *under what circumstances does it break*? If I knew for sure
that a certain object layout always guarantees this trick to work,
then I could configure my codegenerator to always generate wrapper
code that would make this trick reliable. It could be a good
performance win.
Sep 19 2012