pybind11用于使用自定义变量初始化的类

时间:2019-07-17 17:49:27

标签: python c++ pybind11

我是pybind11的新手,并且正在使用它在python中实现一些C ++函数和类。阅读文档,我了解如何实现将标准类型作为变量传递给构造函数的类。我找不到如何传递自定义变量。

简单的示例和解决方案

第一个简单的示例是:

struct Vec {
    float x, y, z;    
    Vec(float x_ = 0, float y_ = 0, float z_ = 0) {
        x = x_;
        y = y_;
        z = z_;
    }
    float func(const int &b) const {
        return x * b.x + y * b.y + z * b.z;
    }

要在python中导入它,我会做(并希望它是正确的):

PYBIND11_MODULE(some_module, m) {

    py::class_<Vec>(m, "Vec");
        .def(py::init<float, float, float>())
        .def("func", &Vec::func)
}

问题

现在,如果我的构造函数不使用floatint,该怎么办?我将显示一个示例:

class Rectangle_xz {
public:
    float x1, x2, z1, z2, y;
    Vec e, c;        
    Refl_t refl;      
    Rectangle_xz(float x1_, float x2_, float z1_, float z2_, float y_,
            Vec e_, Vec c_, Refl_t refl_) :
            x1(x1_), x2(x2_), z1(z1_), z2(z2_), y(y_), e(e_), c(c_), refl(refl_) {}
}

在这种情况下,我的构造函数需要两种不同的类型,VecRefl_t
对于那些接受自定义类型的函数,存在类似的问题:

Vec normal(const Ray &r, Hit_records &hit, Vec &x) const {
        Vec n = Vec(0, 1, 0);
        hit.refl = refl;
        hit.c = c;
        hit.e = e;
        return n.dot(r.d) < 0 ? n : n * -1;
    }

编辑

我尝试了一个简单的示例,以查看初始化一个类后是否可以将该类作为变量传递。

class Person {
public:
    int a, b;
    Person(int a_, int b_) :
        a(a_), b(b_){}  
};

class Gatto {
public:
    Person p1;
    Gatto(Person p1_) : 
        p1(p1_){}   };

PYBIND11_MODULE(person_example, m) {
    py::class_<Person>(m, "Person")
        .def(py::init<int, int>())
        .def_readwrite("a", &Person::a)
        .def_readwrite("b", &Person::b);

    py::class_<Gatto>(m, "Gatto")
        .def(py::init<&Person>())
        .def_readwrite("p1", &Gatto::p1);
}

这现在可行,但是当我将a对象传递给它的构造函数时,我无法从b获取GattoPerson变量。实际上,Gatto仅具有变量p1,该变量返回指向对象Person的指针。

1 个答案:

答案 0 :(得分:-1)

这个简单的例子对我来说不是编译的。但是,将其稍微更改为以下内容即可完成工作:

class Person {
public:
  int a, b;
  Person(int a_, int b_) : a(a_), b(b_) {}
};

class Gatto {
public:
  Person p1;
  Gatto(const Person& p1_) : p1(p1_) {}
};

PYBIND11_MODULE(person_example, m) {
  py::class_<Person>(m, "Person")
      .def(py::init<int, int>())
      .def_readwrite("a", &Person::a)
      .def_readwrite("b", &Person::b);


  py::class_<Gatto>(m, "Gatto")
      .def(py::init<Person>())
      .def_readwrite("p1", &Gatto::p1);
}

此处gatto.p1.agatto.p1.b可在python中访问。