Search code examples
c++design-patternsfactorycreateinstancedlsym

Factory Pattern in C++: generating explicit createInstance()-Method automatically


i have the problem in writing a C++ framework, that users should have less overhead than possible to use it. Users can publish their work to the frameworks by creating a shared library that contains a class, which is derived by a frameworks' BaseClass and implementing an extern "C" createInstance()-method in order to return an instance its' derived class. So the framework can access the user class by calling the createInstance-Method through the shared library with dlsym().

class BaseClass{}
class UserClass : public BaseClass{}

extern "C"{  
   BaseClass* UserXcreateInstance(){
    return new UserClass();
   }                        
}

In framework:

typedef BaseClass* (*CreateInstance) ();
void* handle;
CreateInstance createInstance;
handle = dlopen( "libUserLibrary.so", RTLD_LAZY | RTLD_GLOBAL );
createInstance = reinterpret_cast <CreateInstance*> dlsym( handle, "UserXcreateInstance" );
BaseClass* userX = createInstance();

My Question: Is it possible to generate the UserXcreateInstance()-method, which is redundant in each user library, so that the user don`t have to think about it?

I thought it would be possible with templates+macros, but I haven't yet found a way to do this...

Another approach, I was thinking is directly call the constructor of any user class via dlsym and appropiate name mangling. (I know any namespace + class name from a config file) But I don`t think this a proper solution, especially a constructor call is not the same as a regular function call... but very interesting...


Solution

  • I can't imagine a way to create this automatically without any coding per part of the user. I can imagine ways to simplify it, perhaps using a macro:

    #define OBJECT_CREATOR(X) \
        extern "C" {          \
             BaseClass *UserXCreateInstance() {\
                 return new X(); \
             }\
        }
    

    And the user just need to put on his cpp file:

    OBJECT_CREATOR(UserClass);