tags:

views:

155

answers:

4

Hello, Horrible title I know, horrible question too. I'm working with a bit of software where a dll returns a ptr to an internal class. Other dlls (calling dlls) then use this pointer to call methods of that class directly:

//dll 1
internalclass m_class;
internalclass* getInternalObject() {
    return &m_class;
}

//dll 2
internalclass* classptr = getInternalObject();
classptr->method();

This smells pretty bad to me but it's what I've got... I want to add a new method to internalclass as one of the calling dlls needs additional functionality. I'm certain that all dlls that access this class will need to be rebuilt after the new method is included but I can't work out the logic of why.

My thinking is it's something to do with the already compiled calling dll having the physical address of each function within internalclass in the other dll but I don't really understand it; is anyone here able to provide a concise explanation of how the dlls (new internal class dll, rebuilt calling dll and calling dll built with previous version of the internal class dll) would fit together?

Thanks, Patrick

+2  A: 

You should have returned a ptr to a derived class object as a base class type. Then you can change the derived class freely. Can't change the base class though.

Edit: you may be able to change it a bit. But carefully. Adding methods should work (unless they are virtual). Adding variables may work if you add them at the end.

Thomas
+2  A: 

No, rebuilding is likely not needed.

Behind the scenes, internalclass::method() will be mangled into something like internalclass__method(internalclass* __this). This mangled function is then exported by name from your DLL.

MSalters
It will only be needed if virtual function tables are at play.
xtofl
Except, if method() is virtual. But in this case you'll be fine as long as you add your new function to the end of the vtable.
Ralph
I might have subconciously read too much in "use this pointer to call methods of that class *directly* " and "the already compiled calling dll having the physical address of each function".
MSalters
A: 

Don't touch the existing class and returns a pointer to a derived class in a new function getInternalObject_ex()

luc
+2  A: 

The client dll's 'learn' the actual address of the class' functions at load-time by looking at the export table of the serving dll. So as long as the export table stays compatible, no harm is done.

Compatibility will be broken when your class has a virtual function table, and the functions in it change order. It will also break when linking by ordinal instead of by symbol.

xtofl
So if the method is non virtual it will be okay (even if other methods in the class (the destructor) are virtual?)
Patrick
As long as you link by name, not by ordinal
xtofl
I assume the function order in the vtable is decided by the order they are in the class definition?
Patrick
It will also break if you add more variables to the class (unless they are added to the end) or change the old ones, no?
Thomas
@Thomas: indeed, if your client code also has to do the memory allocation - i.e. if it uses your class' constructor.
xtofl