c++ - Load class from shared library without header file -
i have my_program
loads shared libraries. basicaly user can create 1 project , project can executed my_program
. want load class shared library. i've found example: c++ dynamic shared library on linux
this example great, have problem. don't have header file. so, there possible way load class don't have header file? suppose there isn't. if not mistaken don't think there way load header file dynamically?
if user write class child : public parent
in main program must replace myclass
(from example provided) child. know methods in child class, becase provide baseparent
class pure virtual methods. include baseparent
in main program. still need know class name of project.
what if project class name must my_project? help? know must replace myclass
(from example above) my_project
wouldn't trigger error because main program wouldn't know nothing class my_project
?
i'm open suggestions because literally stuck.
edit: if have class in main program:
class baseparent { public: virtual bool init(const testcase&); virtual void run(); virtual bool done(); }
next 2 classes writen user creates project
class parent : public baseparent { public: bool init(const testcase &test) { //implementation of method } void run() { execute(.....); } bool done() { //implementation of method } //he must define method in child class virtual void execute(...); };
and other class
class child : public parent { public: void execute(...) { //implementation of method } }; extern "c" child* create_object() { return new child; } extern "c" void destroy_object( child* object ) { delete object; }
so, can include baseparent
in main program. if child class return pointer baseparent
can call methods init, done, , run bellow? baseparent
not aware of execute called in run?
void *handle = dlopen(shared_lib, rtld_lazy); if (handle) { baseparent* (*create)(); void (*destroy)(baseparent*); create = (baseparent* (*)())dlsym(handle, "create_object"); destroy = (void (*)(baseparent*))dlsym(handle, "destroy_object"); baseparent* myclass = (baseparent*)create(); myclass->init(test); //wouldn trigger error because it's not implemented in baseparent in child? }
edit 2:
baseparent* (*create)(); void (*destroy)(baseparent*); //other code.... buff path libproject.so void *handle = dlopen(buff, rtld_lazy); if (handle) { create = (baseparent* (*)())dlsym(handle, "create_object"); destroy = (void(*)(baseparent*))dlsym(handle, "destroy_object"); baseparent *a = (baseparent*)create(); a->run(); }else { log(error) << "error in opening lib " << buff; return; }
problem linker (on os x) gives me error:
undefined symbols architecture x86_64: "baseparent::run()", referenced from: vtable baseparent in baseparent "baseparent::init(testcase&)", referenced from: vtable baseparent in baseparent ld: symbol(s) not found architecture x86_64
but on ubuntu 12.04 this:
(gdb) 99 absalgorithm *a = (absalgorithm*)create(); (gdb) program received signal sigsegv, segmentation fault. 0x0000000000000000 in ?? ()
so, run , init method virtual can see above. advice?
upd: correct, think, is
extern "c" baseparent* create_object() { return new child; }
so keep fact child
exists inside user's library, , provide library interface in terms of baseparent
.
with correction, code work (as long not contain other errors, did not check compilability). key idea of polymorphism: if have base class (interface) , have derived class, , code uses methods of interface, code not need know particulars derived class, nor know derived class exists @ all. code needs pointer object, , point of view of code pointer have type interface*
, i.e. pointer interface.
Comments
Post a Comment