如何通过 Python/C API 将 Python 实例传递给 C++

2024-04-26

我通过使用 SWIG 2.0 包装接口来使用 Python (2.7) 扩展我的库,并且有一个我想在其中创建访问者的图形对象。在 C++ 中,接口如下所示:

    struct Visitor
    {
        virtual void OnStateBegin() = 0;
        virtual void OnNode(Node* n) = 0;
        virtual void OnStateEnd() = 0;
    };

我想在Python中定义一个类,它执行等效的操作,所有这些都在Python中定义,这将允许定义访问者:

class GraphVisitor:
    def __init__(self, label):
        self._label = label
        print("__init__(self,{0})".format(self._label))
    def OnStateBegin(self):
        print("OnStateBegin()" + self._label)
    def OnNode(self, i_node):
        print("OnNode()" + self._label)
    def OnStateEnd(self):
        print("OnStateEnd()" + self._label)

我想做的是在 python 脚本中创建 GraphVisitor 的实例,并从 C++ 中为给定实例调用方法 OnStateBegin()、OnNode() 和 OnStateEnd()。这是我想用 Python 做的事情:

#model is a SWIG wrapped class
mvis = GraphVisitor("This is a test")
model.Visit("mvis") # I'm not sure how to pass the instance 'mvis' to C++?

在 Swig 封装的 C++ 中,我不确定如何获取实例“mvis”?我可以毫无问题地调用 Python 中定义的函数,但实例却难住了我!


为了解决这个问题,我从模块中检索了该类,并给出了它的模块名称和类名称(下面的代码假设该模块尚未加载):

void Model::Visit(const char* mod_name, const char* class_name)
{
    PyErr_Clear();
    PyObject* mod_name_obj = PyString_FromString(mod_name);
    PyObject* class_name_obj = PyString_FromString(class_name);

    PyObject* py_module = PyImport_Import(mod_name_obj);
    PyObject* err_1 = PyErr_Occurred();
    if(err_1)
        PyErr_Print();

获得该模块后,我从它的字典中查找该类:

    if(py_module)
    {
        PyObject* py_module_dict = PyModule_GetDict(py_module);
        PyObject* py_class = PyDict_GetItem(py_module_dict, class_name_obj);

我通过在 C++ 中实例化 python 类来稍微简化了我的问题,然后创建了我的访问者,最后访问了它:

        if(py_class && PyClass_Check(py_class) && PyCallable_Check(py_class))
        {
            PyObject* inst = PyInstance_New(py_class, 0, 0);

            if(inst && PyInstance_Check(inst))
            {
                IModel::IVisitorPtr py_visitor = new PyModelVisitor(inst);

                _model->Visit(py_visitor);
            }
        }
    }
}

访问者有 3 个函数 OnStateBegin()、OnNode() 和 OnStateEnd()。我在 SWIG python 绑定生成器中添加了一个选项,用于生成头文件,以便使用以下命令从外部访问 SWIG 运行时-外部运行时选项 http://swig.org/Doc2.0/SWIGDocumentation.html#Modules_external_run_time,所以我可以用 C++ 创建一个类(下面的 INode*),并将其作为 python OnNode() 成员函数的参数传递给 Python,如下所示(为了简洁,删除了错误检查):

VisitorCtrl OnNode(INode* node)
{
    Node* node_impl = new NodeImpl(node);
    PyObject* pynode = SWIG_NewPointerObj(node_impl, SWIG_TypeQuery("Node *"), 0);
    PyObject* result = PyObject_CallMethodObjArgs(_inst, PyString_FromString("OnNode"), pynode, 0);

    long rivis = PyInt_AsLong(result);

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

如何通过 Python/C API 将 Python 实例传递给 C++ 的相关文章

  • Floyd-Warshall 算法:获取最短路径

    假设一个图由一个表示n x n维数邻接矩阵 我知道如何获得所有对的最短路径矩阵 但我想知道有没有办法追踪所有最短路径 Blow是python代码实现 v len graph for k in range 0 v for i in range
  • 如何从数据框的单元格中获取值?

    我构建了一个条件 从我的数据框中提取一行 d2 df df l ext l ext df item item df wn wn df wd 1 现在我想从特定列中获取一个值 val d2 col name 但结果 我得到一个包含一行和一列
  • 如何在matplotlib中基于x轴更改直方图颜色

    我有根据 pandas 数据框计算出的直方图 我想根据 x 轴值更改颜色 例如 If the value is 0 the color should be green If the value is gt 0 the color shoul
  • 操纵 setter 以避免 null

    通常我们有 public string code get set 如果最终有人将代码设置为 null 我需要避免空引用异常 我尝试这个想法 有什么帮助吗 public string code get set if code null cod
  • 为 Python 2.4 改进“with”语句的直接替换

    您能否建议一种方法来编写可在 Python 2 4 中使用的 with 语句的直接替换代码 这将是一个 hack 但它可以让我更好地将我的项目移植到 Python 2 4 EDIT 删除了不相关的元类草图 只需使用 try finally
  • x11 - 导入错误:没有名为“kivy.core.window.window_x11”的模块

    目前我正在尝试构建一个我通过 buildozer 用 Python 和 Kivy 编写的应用程序 无论我在做什么 我都会遇到 window x11 的问题 即使我在代码中注释掉所有与 Windows 相关的内容或执行本文中描述的所有操作 这
  • 特征密集稀疏矩阵乘积是线程化的吗?

    我知道稀疏密集产品是根据文档进行线程化的 https eigen tuxfamily org dox TopicMultiThreading html https eigen tuxfamily org dox TopicMultiThre
  • 使用 AdHocWorkspace 会导致“不支持语言‘C#’”。

    在VS2015中使用Microsoft CodeAnalysis CSharp Workspaces的RC2 这段代码会抛出异常 var tree CSharpSyntaxTree ParseText var workspace new A
  • 如何用 C 语言练习 Unix 编程?

    经过五年的专业 Java 以及较小程度上的 Python 编程并慢慢感觉到我的计算机科学教育逐渐消失 我决定要拓宽我的视野 对世界的一般用处 并做一些 对我来说 感觉更重要的事情就像我真的对机器有影响一样 我选择学习 C 和 Unix 编程
  • 允许使用什么类型的内容作为 C 预处理器宏的参数?

    老实说 我很了解 C 编程语言的语法 但对 C 预处理器的语法几乎一无所知 尽管我有时在编程实践中使用它 所以问题来了 假设我们有一个简单的宏 它扩展为空 define macro param 可以放入宏调用构造中的语法有哪些限制 调用宏时
  • 从事务范围调用 WCF 服务方法

    我有这样的代码 using TransactionScope scope TransactionScopeFactory CreateTransactionScope some methodes calls for which scope
  • 不兼容的类型 - 是因为数组已经是指针吗?

    在下面的代码中 我创建一个基于书籍结构的对象 并让它保存多个 书籍 我设置的是一个数组 即定义 启动的对象 然而 每当我去测试我对指针的了解 实践有帮助 并尝试创建一个指向创建的对象的指针时 它都会给我错误 C Users Justin D
  • 网页抓取 - 如何识别网页上的主要内容

    给定一个新闻文章网页 来自任何主要新闻来源 例如时报或彭博社 我想识别该页面上的主要文章内容 并丢弃其他杂项元素 例如广告 菜单 侧边栏 用户评论 在大多数主要新闻网站上都可以使用的通用方法是什么 有哪些好的数据挖掘工具或库 最好是基于Py
  • .NET JIT 编译的代码缓存在哪里?

    NET 程序首先被编译为 MSIL 代码 当它被执行时 JIT编译器会将其编译为本机机器代码 我想知道 这些JIT编译的机器代码存储在哪里 它只存储在进程的地址空间中吗 但由于程序的第二次启动比第一次快得多 我认为即使在执行完成后 该本机代
  • 使用(linq to sql)更新错误

    我有两个表 通过外键 CarrierID 绑定 Carrier CarrierID CarrierName CarrierID 1 CarrierName DHL CarrierID 2 CarrierName Fedex Vendor V
  • 从 Python 中编译的正则表达式中提取命名组正则表达式模式

    我有一个 Python 正则表达式 其中包含多个命名组 但是 如果先前的组已匹配 则可能会错过与一组匹配的模式 因为似乎不允许重叠 举个例子 import re myText sgasgAAAaoasgosaegnsBBBausgisego
  • 在 Tensorflow 2.0 中的简单 LSTM 层之上添加 Attention

    我有一个由一个 LSTM 和两个 Dense 层组成的简单网络 如下所示 model tf keras Sequential model add layers LSTM 20 input shape train X shape 1 trai
  • Python - 如何将列表保存为图像?

    我生成一个常规列表 是否可以将此列表保存为 JPEG 图像或 PNG 或其他格式 以便我可以打开图像并查看它 我目前正在尝试使用 python 成像库 PIL 来解决这个问题 这是可能的解决方案之一 使用以下方法创建一个空图像对象 Imag
  • python中匹配3个或更多相同的字符

    我正在尝试使用正则表达式在字符串中查找三个或更多相同的字符 例如 你好 不匹配 噢 会的 我尝试过做类似的事情 re compile 1 3 a zA Z re compile w 1 5 但似乎都不起作用 w 1 2 是您正在寻找的正则表
  • FindAsync 很慢,但是延迟加载很快

    在我的代码中 我曾经使用加载相关实体await FindAsync 希望我能更好地遵守 C 异步指南 var activeTemplate await exec DbContext FormTemplates FindAsync exec

随机推荐