pluggable code with dynamic libraries

  • Thread starter Daniel Luis dos Santos
  • Start date
D

Daniel Luis dos Santos

Hello,

I have a piece of code that relies on a dynamic library for
implementing specific functionality. In other words, the first piece of
code supports plugging in the other library. To do that I am using the
dlopen api.

I want to make the loading of the code obey a class interface from
which all plugins should derive.
As usual in this situation I have one C function that creates instances
of the plugin class, and another one for calling their destructor.

Problem is that, when I get the function that creates the instances
(using dlsym), there is no way of knowing if it conforms to the agreed
signature, mainly if the returned object is a descendent of the plugin
class. What can I do to enforce this ?
 
J

James Kanze

I have a piece of code that relies on a dynamic library for
implementing specific functionality. In other words, the first
piece of code supports plugging in the other library. To do
that I am using the dlopen api.
I want to make the loading of the code obey a class interface
from which all plugins should derive. As usual in this
situation I have one C function that creates instances of the
plugin class, and another one for calling their destructor.
Problem is that, when I get the function that creates the
instances (using dlsym), there is no way of knowing if it
conforms to the agreed signature, mainly if the returned
object is a descendent of the plugin class. What can I do to
enforce this ?

You can't, really. Two possibilities which come more or less
close:

If portability is not a concern, use a C++ function with the
signature:
void getObject( Base*& )
and call it with the mangled name. You still really can't
prevent the dynamic code from putting anything it wants in the
Base*, using casts if necessary; you also risk problems if Base
evolves, and the dynamic code uses an older, incompatible
version of Base (or even that it defines its own, completely
different version of Base). But it does require the client code
to at least recognize that Base exists, and if you put Base in a
namespace whose name evolves with the version, you can also trap
versionning problems.

Alternatively: don't use dlsym at all: require the client code
to contain a static variable whose initializer registers the
object somewhere. If the registry only accepts Base*, then the
client code can only register an object of type Base or which
derived from Base (with the usual limitations concerning casts
and versioning).
 

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

Members online

No members online now.

Forum statistics

Threads
474,160
Messages
2,570,889
Members
47,420
Latest member
ZitaVos505

Latest Threads

Top