C++ 如何检查动态库是否正确实现接口
我正在尝试从动态库加载一个类。 此类需要从名为C++ 如何检查动态库是否正确实现接口,c++,c++11,dll,shared-libraries,C++,C++11,Dll,Shared Libraries,我正在尝试从动态库加载一个类。 此类需要从名为IDisplayModule的接口继承: class IDisplayModule { public: virtual ~IDisplayModule() = default; virtual const std::string &getName() const = 0; }; 我创建了一个DLLoader类,用于加载动态库: template <typename T> class DLLoader { priv
IDisplayModule
的接口继承:
class IDisplayModule {
public:
virtual ~IDisplayModule() = default;
virtual const std::string &getName() const = 0;
};
我创建了一个DLLoader
类,用于加载动态库:
template <typename T>
class DLLoader {
private:
std::string _libraryPath;
void *_handle;
public:
DLLoader<T>(const std::string &libraryPath) try : _libraryPath(libraryPath), _handle(NULL) {
_handle = dlopen(_libraryPath.c_str(), RTLD_GLOBAL | RTLD_NOW);
if (!_handle)
throw DLLoaderException("On dlopen of " + _libraryPath, "DLLoader");
} catch (DLLoaderException &e) {
throw e;
};
T *getInstance(const std::string &entryPoint) const {
T *(*fptr)(void);
T *obj = NULL;
void *ret = dlsym(_handle, entryPoint.c_str());
if (!ret)
throw DLLoaderException("On dlsym of " + _libraryPath + dlerror() + "DLLoader");
fptr = reinterpret_cast<T *(*)(void)>(ret);
obj = dynamic_cast<T *>(fptr());
if (!obj)
throw DLLoaderException("On cast of " + _libraryPath + dlerror() + "DLLoader");
return (obj);
};
~DLLoader<T>() {
dlclose(_handle);
};
};
下面是一个关于错误库的错误类的例子。所以
:
class WrongClass : public IDisplayModule {
private:
std::string _name;
public:
lib1();
~lib1();
};
extern "C" {
IDisplayModule *entryPoint()
return (new WrongClass());
}
您还需要考虑一件事:std::string
的实现在不同的编译器甚至不同版本的编译器之间差异很大。在传递无法完全控制的数据结构时,需要非常小心。这是如何编译的getName
是一个纯虚拟函数ErrorClass
必须实现它,否则您无法创建该类型的实例。它可以编译,因为创建ErrorClass的家伙拿走了我的IDisplayModule,但他删除了getName方法。这样,他就可以用错误的类和IDisplayModuleWell编译他的库,在这种情况下,您的IDisplayModule
不是ErrorClass
的IDisplayModule
。它们是两种不同的类型,你试图重新解释它们,这违反了严格的别名规则。是的,就是这样。这家伙没有实现好的IDisplayModule
,但是我的程序怎么能检测到它不是一个好的实现呢?
class WrongClass : public IDisplayModule {
private:
std::string _name;
public:
lib1();
~lib1();
};
extern "C" {
IDisplayModule *entryPoint()
return (new WrongClass());
}