Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I'm writing a proxy class that loads a shared library with dlopen() and forwards its member functions to the appropriate members of the proxied class instance inside the loaded shared object behind the scenes.

For example, the shared object has a Person class:

class Person
{
    ...
    void setName(std::string name);
};

I've added a wrapper file that includes the person.h header and defines the following symbol:

extern "C" {
    void Person_setName(void* instancePointer, std::string name);
}

This call just forwards to the person object which is the first argument, extern "C" to avoid the whole name mangling issue. On the client side I've written a Person class with the same members that holds a pointer to the wrapped class and forwards all calls.

Now some question arise:

  1. is there a better way to instantiate and use a class from a loaded shared object? I've found some other solution that can live without the wrappers, but it's discouraged on Usenet and highly dependent on GCC and its version, and undefined behavior, so I decided against that route.
  2. is there a way to automate the creation of those wrappers? They are all just adding a first argument that is a pointer to an instance to each method and forward to the real thing. There has to be some template magic for that, no? Currently I'm using some macros for the job but I'd be interested in a template solution.
  3. Maybe there is some tool that can do such a thing automatically, like SWIG? As far as I've seen SWIG is just for exporting a C++ interface to high level languages.
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
348 views
Welcome To Ask or Share your Answers For Others

1 Answer

is there a better way to instantiate and use a class from a loaded shared object?

If you want to be safe and support any shared object (i.e. compiled by any compiler/flags etc.), then no: you have to go through the C ABI.

Remember you should not use C++ objects in the interface either, e.g. like the std::string you are passing in Person_setName.

is there a way to automate the creation of those wrappers? There has to be some template magic for that, no? Currently I'm using some macros for the job but I'd be interested in a template solution.

No, you cannot create member functions on the fly (we do not have reflection, metaclasses and similar compile-time features yet).

They are all just adding a first argument that is a pointer to an instance to each method and forward to the real thing.

You can create a variadic template that forwards arguments to a given extern "C" function, of course, but you are not really getting anything useful from that compared to simply calling the C functions. In other words, don't do that: either create a proper C++ class or leave the users to call the C functions.

Maybe there is some tool that can do such a thing automatically, like SWIG? As far as I've seen SWIG is just for exporting a C++ interface to high level languages.

I have used Clang's tooling support in the past to perform similar tasks as a pre-build step, so it is indeed possible!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...