定义共享库中抽象类的接口
Defining interface of abstract class in shared library
假设我有一个抽象基类,定义如下:
interface.hpp
#ifndef INTERFACE_HPP
#define INTERFACE_HPP 1
class interface{
public:
virtual void func() = 0;
};
#endif // INTERFACE_HPP
然后将翻译单元test.cpp
编译为共享对象test.so
:
test.cpp
#include "interface.hpp"
#include <iostream>
class test_interface: public interface{
public:
void func(){std::cout << "test_interface::func() calledn";}
};
extern "C"
interface &get_interface(){
static test_interface test;
return test;
}
如果我在可执行文件中打开共享对象,并尝试像这样调用get_interface
:
#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);
}
(假装我做了错误检查)
行为是否定义良好?还是说我假设这种方法总是有效,这是在伤害我自己?
请记住,我将只使用clang和gcc
一个问题是,您希望protected: ~interface()
阻止客户端删除interface
。
interface
,请记住只在类的末尾添加方法,而不要添加新的虚拟覆盖(具有相同名称的函数)。(在实践中,我见过重写被聚集在一起,即使它们没有聚集在头文件中)。
如果你想要不止一个接口(比如,你的接口继承了另外两个接口),使用virtual
继承。根据我的经验,事后添加新的virtual
父母也是有问题的。
这些都不是c++标准定义的,它与二进制接口和运行时加载代码的主题无关。然而,以上是我使用类似技术的经验(不可否认,使用指针而不是引用,使用MSVC而不是gcc/clang)。
您必须跟踪您使用的编译器上的ABI。如果您在这样的接口上传递std
结构,请注意它们有时会改变布局(例如,gcc中的std::string
从引用计数变为不引用计数,或者std::list
变为0 (1)size
),并且它们不太可能在编译器之间实现布局兼容(好吧,标准库,不同的编译器倾向于默认使用不同的库)。
相关文章:
- 抽象类/接口中的空方法是否被认为是一种好的做法?
- 可以模板抽象类接口
- C 分开的抽象类(接口),用于某些通用读取和/或写入访问
- C++中的抽象类与接口
- 我可以在c++接口(抽象类)中包含什么
- 不可变接口的抽象类
- 如何在C++中编程到接口/抽象类
- 接口与抽象类C++
- 抽象类/接口C++
- 防止在C++中对抽象类接口进行子类化
- 接口与抽象类?(一般OOP)
- 接口、协议和抽象类
- C#对导出抽象类/接口的C++DLL函数的消耗
- 它是抽象类还是纯虚拟(接口)
- 抽象类作为接口,不带虚函数表
- 接口(抽象类)设计的最佳方法
- 接口/抽象类应该只包含纯虚拟方法
- 来自接口(抽象类)的多重继承
- c++强制操作符==重载接口抽象类
- 回调(std::function/std::bind)与接口(抽象类)的优缺点