从同一命名空间[C++/pybind11]中的类访问静态变量时出现ImportError



首先,我对C++编程和pybind11相对陌生。下面的例子应该解释我的问题:

a.h:

namespace test {
class A {
public:
static int something;
};
void setSomething(int input);
}

a.cpp:

#include <pybind11/pybind11.h>
#include "a.h"
int test::A::something;
void test::setSomething(int input) {
A::something = input;
}
PYBIND11_MODULE(a, handle) {
handle.doc() = "I'm a docstring hehe";
handle.def("setSomething", &test::setSomething);
}

b.h:

namespace test {
class B {
public:
B();
int getSomething() const;
};
}

b.cpp:

#include <pybind11/pybind11.h>
#include "a.h"
#include "b.h"
namespace py = pybind11;
// int test::A::something;
test::B::B(){}
int test::B::getSomething() const {
return A::something;
}
PYBIND11_MODULE(b, handle) {
handle.doc() = "I'm a docstring hehe";
py::class_<test::B>(handle, "B")
.def(py::init())
.def("getSomething", &test::B::getSomething);
}

所以我有两个类A和B,它们在a.cppb.cpp中定义,都有头文件a.hb.h。基本上,我试图访问B类中A类的静态变量。现在,如果我使用CMake编译它们并尝试运行test.py文件,我会得到一个ImportError,告诉我undefined symbol: _ZN4test1A9somethingE。我希望这不是一个愚蠢的问题。提前感谢您的帮助!

编辑:如果我在类内定义变量,它不会获取在类外之前或之后设置的值。

假设您已经使用上面的代码构建了两个模块。类似于a.sob.so,您将使用单独的import aimport b语句将它们导入Python。

这是行不通的:您需要通过同一个二进制对象访问静态变量。即使链接正确,::test::A::somethinga.sob.so中也会有不同的地址。(如果你使用的是pybind中的构建系统助手,你甚至不会注意到,因为当你导入两个模块时,"默认隐藏符号"将防止链接错误。(

您需要确保.cpp和b.cpp都链接到同一个库对象中。

在pybind中,PYBIND11_MODULE的第一个参数等同于您正在构建的共享对象库。如果你想像这样模块化地排列你的软件,我建议在一个单独的源文件中定义pybind模块,然后将模块对象(你已经命名为handle(传递给负责添加类绑定的函数。

示例:

module.cpp

PYBIND11_MODULE(m, handle) {
handle.doc() = "I'm a docstring hehe";
bind_a(handle);
bind_b(handle);
}

a.cpp:

void bind_a(py::module& m) {
m.def("setSomething", &test::setSomething);
}

b.cpp:

void bind_b(py::module& m) {
py::class_<test::B>(m, "B")
.def(py::init())
.def("getSomething", &test::B::getSomething);
}

最新更新