使用 pybind11 在类方法中调用嵌入函数

2023-12-21

我正在开发一个使用 pybind11 嵌入 python 的 C++ 应用程序,在尝试从类方法调用嵌入函数时遇到了一些问题。

首先是我的绑定:

#ifdef _DEBUG
#undef _DEBUG
#include <python.h>
#define _DEBUG
#else
#include <python.h>
#endif
#include <embed.h>

namespace py = pybind11;
using namespace py::literals;

void DebugInfo(std::string string_)
{
    String LogMessage_(string_.c_str());
    LOGINFO(LogMessage_);
}

PYBIND11_EMBEDDED_MODULE(Test, m) {
    m.def("DebugInfo", &DebugInfo, "Posts message to DEBUGINFO");
}

然后我可以有一个 .py 文件:

import Test
test.DebugInfo("I'm a lumberjack and that's OK")

它会打印得很好来调试

当我尝试从类方法中调用它时,麻烦就开始了。

import Test
class PyTest(object):
    def __init__(self):
        test.DebugInfo("I'm a lumberjack and that's OK")

test = PyTest()

当它运行时,它会针对cast.h抛出异常,特别是针对该函数的第1985行:

template <return_value_policy policy>
class unpacking_collector {
public:
    template <typename... Ts>
    explicit unpacking_collector(Ts &&...values) {
        // Tuples aren't (easily) resizable so a list is needed for collection,
        // but the actual function call strictly requires a tuple.
        auto args_list = list();
        int _[] = { 0, (process(args_list, std::forward<Ts>(values)), 0)... };
        ignore_unused(_);

        m_args = std::move(args_list);
    }

    const tuple &args() const & { return m_args; }
    const dict &kwargs() const & { return m_kwargs; }

    tuple args() && { return std::move(m_args); }
    dict kwargs() && { return std::move(m_kwargs); }

    /// Call a Python function and pass the collected arguments
    object call(PyObject *ptr) const {
        PyObject *result = PyObject_Call(ptr, m_args.ptr(), m_kwargs.ptr());
        if (!result)
            throw error_already_set();  //EXCEPTION THROWS HERE!
        return reinterpret_steal<object>(result);
    }

因为这可能与我从主应用程序中调用整个过程的方式相关

//Start the Python Interpreter
py::scoped_interpreter guard{};
//Python variables
py::object thing_;
std::string test_py = Import_File("test.py");
auto locals = py::dict();
py::exec(test_py, py::globals(), locals);
thing_ = locals["test"].cast<py::object>();
thing_.attr("start")();

和 test.py 的内容

import Test
class PyTest(object):
    def __init__(self, message = "Test Object initialized"):
        self.message = message
        iterstr = str(self.iter)
        message = self.message + iterstr
        self.iter = 0
        Test.DebugInfo(message)
    def start(self):
        self.message = "Starting Python Object"
        self.iter = self.iter + 1
        iterstr = str(self.iter)
        message = self.message + iterstr
        Test.DebugInfo(message)
    def update(self):
        self.message = "Python Object Update Cycle:"
        self.iter = self.iter + 1
        iterstr = str(self.iter)
        message = self.message + iterstr
        Test.DebugInfo(message)

test = PyTest()

我不确定我是否遇到了 pybind11 的限制、其中的错误,或者我是否只是把整个事情搞砸了。

任何见解将不胜感激。


这也被作为一个问题提交给pybind11 here: https://github.com/pybind/pybind11/issues/1452 https://github.com/pybind/pybind11/issues/1452

我遇到了这个SO和问题,但我想通了。将其复制到此处,供将来第一个偶然发现此问题的人使用

基本上,你实际上并不想要空白py::dict for locals;它会导致各种各样的问题。如果您查看文档或测试中的嵌入示例代码,localsvalue 总是复制全局范围。

See:

* https://pybind11.readthedocs.io/en/stable/advanced/embedding.html

* https://github.com/pybind/pybind11/blob/master/tests/test_embed/test_interpreter.cpp#L57

您的选择是复制全局范围,或者在这种情况下,只是不传入locals

py::scoped_interpreter guard{}; 
auto globals = py::globals();
py::exec(test_py, globals);
thing_ = globals["Object"].cast<py::object>(); 
thing_.attr("start")();

看起来在顶级代码(不在任何模块内)的情况下,globals变量保存此范围内的值。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 pybind11 在类方法中调用嵌入函数 的相关文章

  • 如何使用 LINQ ForEach 更改 List

    我有一个List
  • 求 a 范围内的 pow(a^b)modN

    对于给定的b and N以及一系列a say 0 n 我需要找到ans 0 n 1 where ans i 没有a s为此pow a b modN i 我在这里搜索的是可能的重复pow a b modN对于一系列a 以减少计算时间 例子 i
  • 在子目录中构建共享库

    我正在尝试构建一个使用一些 C 代码的 R 包 我有一个编译为可执行文件的 C 库 可以从命令行调用 有一个与之关联的 Makefile 我正在尝试获取信息here http cran r project org doc manuals R
  • 如何从 std::vector 中删除元素而不调整其大小

    迭代器擦除 迭代器位置 迭代器擦除 首先是迭代器 迭代器最后 擦除元素 从向量中删除 容器可以是单个元素 位置 或一系列元素 第一个 最后一个 这有效地减少了向量 大小除以元素数量 删除 调用每个元素的 之前的析构函数 and remove
  • 外部剃刀视图看不到外部模型

    我对外部剃刀视图有疑问 在我的项目中 我有主 mvc Web 程序集和动态加载的外部类库程序集 来自 DB 及其自己的控制器 视图和模型 这些程序集在运行时不会直接引用和加载 我能够通过为控制器创建自定义控制器工厂 为视图创建自定义虚拟路径
  • 如何在 C++ 中从模板基类的构造函数调用模板超类的构造函数?

    我正在使用 sublimetext3 用 c 进行编程 我的程序有一个名为 Array 的超类和一个名为 IntArray 的子类 这两个类都是模板类 目前 我在编译该程序时遇到问题 它不断在我的 IntArray cpp 文件中给出错误
  • MVVM 同步集合

    是否有一种标准化方法可以将 Model 对象集合与 C 和 WPF 中匹配的 ModelView 对象集合同步 我正在寻找某种类 可以使以下两个集合保持同步 假设我只有几个苹果 并且可以将它们全部保存在内存中 换句话说 我想确保如果我将 A
  • 导入tensorflow模块在tensorflow 2中很慢

    有关的 导入 TensorFlow contrib 模块在 TensorFlow 1 2 1 中速度很慢 https stackoverflow com questions 45093653 import tensorflow contri
  • 使用私有构造函数的 C# 单元测试类?

    好吧 我刚刚收到一个作业 我必须对具有私有构造函数的类执行单元测试 现在 当所有方法也都是非静态时 我该如何在不初始化类的情况下进行单元测试 有什么方法可以对具有私有构造函数的类进行单元测试 无需反射 如果您无法将类公开 您仍然可以通过以下
  • 如果 .txt 文件不存在,则创建一个,如果存在则追加新行

    我想创建一个 txt 文件并写入它 如果该文件已经存在 我只想添加更多行 string path E AppServ Example txt if File Exists path File Create path TextWriter t
  • 解析通过asp:FileUpload上传的XML文件

    我有一个场景 用户将上传 XML 文件 我想将该文件添加到数据库中的表中 不过 困难的部分是我需要解析文件 然后将一些信息添加到一些不同的表中 显示如何获取 XML 文件的每个示例都使用 URI 来获取文件 但是如何直接从数据库获取文件 或
  • UWP - 绑定枚举差异

    我遇到了一个非常有趣的问题 假设 UWP 应用中有以下 XAML 页面内容
  • Excel 2007 中的数值 - 底层 xml 文件中的表示与存储

    这个问题与 NET和OpenXml有关 我已经阅读了以下文章 它有很好的解释 但没有回答我的问题 Excel 2007 中数值的可视化与底层 xml 文件不一致 https stackoverflow com questions 58594
  • 如何让 PCRE 与 C++ 一起使用?

    这是一个新手问题 但我希望我能尽可能清楚地表达我的问题 我正在尝试用 C 进行模式匹配 我已经从以下位置下载了 PCRE 的 Win32 版本here http gnuwin32 sourceforge net packages pcre
  • WPF MVVM后台打印数据绑定问题

    我正在使用 wpf mvvm 开发一个销售点应用程序 在交易生命周期的许多阶段 都会在后台打印收据 我已经使用其他示例在后台生成和打印收据 我正在后台打印一个 UserControl 一切看起来都很棒 然后 我为该控件创建了 ViewMod
  • 如何从Python列表中的CSV文件的单个单元格中写入单词集?

    dataList cyclone twister thunderstorm supercell wind weatherradar storm waterspout tropicalcyclone hurricane typhoon sno
  • 将 R 值传递给采用 L 值的函数时出现过载歧义

    我有 2 个重载函数 一个采用 L 值 另一个采用 R 值 目的是让该函数可以像这样调用 Obj obj foo obj OR foo Obj 所以 我写了2个重载函数 template
  • 如何进行平衡组捕获?

    假设我有这个文本输入 tes tR R abc aD mnoR xyz 我想提取 ff 输出 R abc R xyz D mnoR xyz R R abc aD mnoR xyz 目前 我只能使用平衡组方法提取组内的内容 如中所示msdn
  • 预览MouseMove 与 MouseMove

    我有相当多的 XAML 经验 但最近我注意到我的大多数同事都使用预览鼠标移动代替鼠标移动事件 我一直用鼠标移动它对我很有帮助 但我忍不住问我什么时候应该使用预览鼠标移动什么时候鼠标移动 有什么区别 各自有什么优点和缺点等等 PreviewM
  • Json.net 将数字属性序列化为字符串

    我正在使用 JsonConvert SerializeObject 序列化模型对象 服务器期望所有字段都是字符串 我的模型对象具有数字属性和字符串属性 我无法向模型对象添加属性 有没有办法将所有属性值序列化为字符串 我必须只支持序列化 而不

随机推荐