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

ImportError when accessing static variables from class in same namespace [C++/pybind11]

首先,我对 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);
}

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

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

想必你已经使用上面的代码构建了两个模块。 a.sob.so 之类的东西,您可以使用单独的 import aimport b 语句将其导入 Python。

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

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

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

示例:

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);
}