python - 使用 pybind11 包装 C++ 抽象类时出错
问题描述
我试图做一个简单的例子来用pybind包装一个抽象的C++类。代码是:
#include <pybind11/pybind11.h>
#include <ostream>
#include <iostream>
namespace py = pybind11;
using namespace std;
class Base
{
public:
virtual void test() = 0;
};
class Derived: public Base
{
public:
void test() {cout << "Test";}
};
PYBIND11_MODULE(example,m) {
py::class_<Base, Derived>(m, "Base")
.def(py::init<>())
.def("test", &Derived::test);
}
当我运行以下命令时
c++ -O3 -Wall -shared -std=c++11 -fPIC `python3 -m pybind11 --includes` abstract_test.cpp -o example`python3-config --extension-suffix`\n
我得到错误:
In file included from abstrakt_test.cpp:1:
/home/anaconda3/envs/pybind/lib/python3.8/site-packages/pybind11/include/pybind11/pybind11.h: In instantiation of ‘Return (Derived::* pybind11::method_adaptor(Return (Class::*)(Args ...)))(Args ...) [with Derived = Base; Return = void; Class = Derived; Args = {}]’:
/home/anaconda3/envs/pybind/lib/python3.8/site-packages/pybind11/include/pybind11/pybind11.h:1118:45: required from ‘pybind11::class_<type_, options>& pybind11::class_<type_, options>::def(const char*, Func&&, const Extra& ...) [with Func = void (Derived::*)(); Extra = {}; type_ = Base; options = {Derived}]’
abstrakt_test.cpp:23:36: required from here
/home/anaconda3/envs/pybind/lib/python3.8/site-packages/pybind11/include/pybind11/pybind11.h:1032:19: error: static assertion failed: Cannot bind an inaccessible base class method; use a lambda definition instead
static_assert(detail::is_accessible_base_of<Class, Derived>::value,
^~~~~~
/home/anaconda3/envs/pybind/lib/python3.8/site-packages/pybind11/include/pybind11/pybind11.h:1034:12: error: cannot convert ‘void (Derived::*)()’ to ‘void (Base::*)()’ in return
return pmf;
^~~
解决方案
您还需要“包装” Base
。否则,您将在导入时收到以下异常:
ImportError: generic_type: type "Derived" referenced unknown base type "Base"
此外,包装顺序Derived
是错误的:
py::class_<Derived, Base>(m, "Derived")
完整示例:
PYBIND11_MODULE(example,m) {
py::class_<Base>(m, "Base");
py::class_<Derived, Base>(m, "Derived")
.def(py::init<>())
.def("test", &Derived::test);
}
推荐阅读
- c - 除了 /dev/input/eventx 之外,还有基于更高级别(字符?)的方式来访问 Linux 键盘吗?
- c# - LINQ 的质数不起作用
- php - 需要帮助来调试 PHP 代码
- python - 在heroku / module not found错误上部署django应用程序的问题
- sqlite - 按类型加减
- ipython - 在不重新启动的情况下重置 iPython %run file.py
- javascript - 如何使用 Handlebars 编写一行 If 语句?
- javascript - PHP 在 URL POST 上打开一个新标签页
- python - python panda:返回常见行的索引
- c - 如何在管道的文件描述符上的线程块中进行 read()?