c++ - Defining interface of abstract class in shared library -
say have abstract base class defined so:
interface.hpp
#ifndef interface_hpp #define interface_hpp 1 class interface{ public: virtual void func() = 0; }; #endif // interface_hpp
then compile translation unit test.cpp
shared object test.so
:
test.cpp
#include "interface.hpp" #include <iostream> class test_interface: public interface{ public: void func(){std::cout << "test_interface::func() called\n";} }; extern "c" interface &get_interface(){ static test_interface test; return test; }
if open shared object in executable , try call get_interface
this:
#include <dlfcn.h> #include "interface.hpp" int main(){ void *handle = dlopen("test.so", rtld_lazy); void *func = dlsym(handle, "get_interface"); interface &i = reinterpret_cast<interface &(*)()>(func)(); i.func(); // print "test_interface::func() called" dlclose(handle); }
(just pretend did error checking)
is behaviour defined? or stepping on own toes assuming work?
keep in mind ever using clang , gcc
one gotcha want protected: ~interface()
discourage clients deleting interface
.
a second, practical issue if modify interface
, remember add methods @ end of class only, , not add new virtual overrides (functions same name). (in practice, have seen overrides clustered together, if not clustered in header file).
if want more single interface (say, interface inherits 2 other interfaces), use virtual
inheritance. adding new virtual
parents after fact has in experience proved problematic well.
none of defined c++ standard, agnostic on subject of binary interfaces , run time loading of code. however, above experience using similar technique (admittedly, pointers instead of references, , using msvc instead of gcc/clang).
you have keep track of abi on compilers use. if pass std
structures on such interface, aware change layout (std::string
in gcc going reference counted not, example, or std::list
getting o(1) size
), , not layout-compatible between compilers (well, standard libraries, different compilers tend use different ones default).
Comments
Post a Comment