【问题标题】:ImportError when accessing static variables from class in same namespace [C++/pybind11]从同一命名空间中的类访问静态变量时出现 ImportError [C++/pybind11]
【发布时间】:2022-01-13 00:08:03
【问题描述】:

首先,我对 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。我希望这不是一个愚蠢的问题。提前感谢您的帮助!

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

【问题讨论】:

    标签: python c++ cmake pybind11


    【解决方案1】:

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

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

    您需要确保 a.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);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-22
      • 2017-04-30
      • 1970-01-01
      • 2017-01-24
      • 1970-01-01
      相关资源
      最近更新 更多