1

When using dynamic libraries, I understand that we should only pass Plain Old Data-structures across boundaries. So can we pass a pointer to base ?

My idea is that the application and the library could both be aware of a common Interface (pure virtual method, = 0). The library could instantiate a subtype of that Interface, And the application could use it.

For instance, is the following snippet safe ?

// file interface.h

class IPrinter{
    virtual void print(std::string str) = 0;
 };

-

// file main.cpp

int main(){
    //load plugin...
    IPrinter* printer = plugin_get_printer();
    printer->print( std::string{"hello"} );
}

-

// file plugin.cpp (compiled by another compiler)

IPrinter* plugin_get_printer(){
    return new PrinterImpl{};
}
Julien__
  • 1,962
  • 1
  • 15
  • 25
  • 1
    *If you are on windows* you are basically redesigning [COM](https://msdn.microsoft.com/en-us/library/ms694363(v=vs.85).aspx). It solves the problems you're talking about in an elegant enough but more importantly well documented fashion. I dont know enough about non-windows platforms to comment on those though. – Mike Vine Feb 12 '15 at 23:51

2 Answers2

1

The presence of virtual functions in your class means that your class is going to have a vtable, and different compilers implement vtables differently.

So, if you use classes with virtual methods across DLL calls where the compiler used on the other side is different from the compiler that you are using, the result is likely to be spectacular crashes.

In your case, the PrinterImpl created by the DLL will have a vtable constructed in a certain way, but the printer->print() call in your main() will attempt to interpret the vtable of IPrinter in a different way in order to resolve the print() method call.

Mike Nakis
  • 56,297
  • 11
  • 110
  • 142
1

This snippet is not safe:

  • the two sides of your DLL boundaries do not use the same compiler. This means that the name mangling (for function names) and the vtable layout (for virtual functions) might not be the same (implementation specific.

  • the heap on both sides may also be managed differently, thus you have risks related to the deleting of your object if it's not done in the DLL.

This article presents very well the main challenges with binary compatible interfaces.

You may however pass to the other side of the mirror a pointer, as part of a POD as long as the other part doesn't us it by iself (f.ex: your app passes a pointer to a configuration object to the DLL. Later another DLL funct returns that pointer to your app. Your app can then use it as expected (at least if it wasn't a pointer to a local object that no longer exists) .

Christophe
  • 68,716
  • 7
  • 72
  • 138
  • Thanks for your answer. The article is very interesting ! About the snippet `std::vector *pVec = getVectorFromDll();`, I read : _"If this were a container that implemented its own sort method such as std::list<>, calling the containers own sort method would be safe because it would use the correct implementation in the DLL."_ **Does it mean that we can use non polymorphic object created on the other side ?** – Julien__ Feb 13 '15 at 00:22
  • No, this quote was about using standard (template) algorithm in the EXE on a collection of the DLL: assumptions of the EXE compiler might not be valid for DLL side ! It says that if you would call a method form the collection (aka compiled with DLL), you wouldn't have this mixup. About using non polymorphic objects, read the section "Non-POD Types": It's very likely to fail, unless you use exactly the same compiler on both sides. Then it could work but requires some careful consistency checks (see also: http://stackoverflow.com/questions/3564985/returning-stdstring-stdlist-from-dll) – Christophe Feb 13 '15 at 07:27
  • 1
    @Chistophe, please see this related SO question : http://stackoverflow.com/questions/28500533/c-plugin-pass-object-across-boundary-emulating-it – Julien__ Feb 13 '15 at 16:54
  • This answer is a good C++03 answer. In C++11, POD as a concept is basically obsolete, and you should be talking about standard layout. – Yakk - Adam Nevraumont Feb 13 '15 at 18:57