boost::python 和 swig 集成

发布于 2024-12-12 02:58:55 字数 484 浏览 0 评论 0原文

我有两个课程,第一个名为“Radish”,第二个名为“RadishCont”。 所有代码都是用C++编写的,需要在python中使用。

Radish已经使用SWIG接触了python;相反,RadishCont 已使用 boost::python 公开。

我需要在类 RadishCont 中添加一个具有以下语法的方法:

Radish* get_radish()
{
    return &radish;
}

其中“radish”是 RadishCont 中包含的 Radish 实例。

当我执行 python 代码时,我收到此异常:

TypeError: No Python class registered for C++ class Radish

所以,我的问题是:如何使此方法在 python 中工作而不使用 SWIG 重写 RadishCont ?

I have two classes, the first called "Radish" and the second called "RadishCont".
All the code is written in C++ and need to be used in python.

Radish have been exposed to python using SWIG; RadishCont, instead, have been exposed using boost::python.

I need to add a method into the class RadishCont that has this syntax:

Radish* get_radish()
{
    return &radish;
}

Where "radish" is a Radish instance contained in RadishCont.

When I execute the python code I receive this exception:

TypeError: No Python class registered for C++ class Radish

So, my question is: how can I make this method work in python without rewriting RadishCont using SWIG ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

对岸观火 2024-12-19 02:58:55

我非常确定您最好重写 SWIG 界面以包含新功能。 SWIG 使用类/函数的内部注册系统,该系统与 boost::pythons 系统不兼容(或者至少不是开箱即用的)。

I'm pretty sure that you are better off rewriting your SWIG interface to include the new function. SWIG uses a internal registration system for classes/functions which is not compatible with boost::pythons system (or at least not out of the box).

删除会话 2024-12-19 02:58:55

最后,我做到了。

我在我的 boost python 模块中创建了一个类实例,如下所示:

class_<Radish>("Radish");

我创建了一个如下所示的转换器函数:

static void* radishConvert(PyObject* obj)
{
    char thisStr[] = "this";
    //first we need to get the this attribute from the Python Object
    if (!PyObject_HasAttrString(obj, thisStr))
            return NULL;

    PyObject* thisAttr = PyObject_GetAttrString(obj, thisStr);
    if (thisAttr == NULL)
            return NULL;
    //This Python Object is a SWIG Wrapper and contains our pointer
    void* pointer = ((PySwigObject*)thisAttr)->ptr;
    Py_DECREF(thisAttr);
    return pointer;
}

其中 PySwigObject 是一个如下所示的结构:

struct PySwigObject 
{
    PyObject_HEAD 
    void * ptr;
    const char * desc;
};

最后,我已经注册了我的转换器:

boost::python::converter::registry::insert(&radishConvert, type_id<Radish>());

这非常有效,我可以从 SWIG 获取对象将其传递给 boost::python。逆过程仍未解决,但对我来说已经足够了。

这是我用来寻找解决方案的指南:
http://wiki.python.org/moin/ boost.python/HowTo#SWIG_exposed_C.2B-.2B-_object_from_Python

At the end, I have done it.

I have created a class instance in my boost python module like this:

class_<Radish>("Radish");

I have created a converter function like this:

static void* radishConvert(PyObject* obj)
{
    char thisStr[] = "this";
    //first we need to get the this attribute from the Python Object
    if (!PyObject_HasAttrString(obj, thisStr))
            return NULL;

    PyObject* thisAttr = PyObject_GetAttrString(obj, thisStr);
    if (thisAttr == NULL)
            return NULL;
    //This Python Object is a SWIG Wrapper and contains our pointer
    void* pointer = ((PySwigObject*)thisAttr)->ptr;
    Py_DECREF(thisAttr);
    return pointer;
}

Where PySwigObject is a struct like this:

struct PySwigObject 
{
    PyObject_HEAD 
    void * ptr;
    const char * desc;
};

Last, I have registered my converter:

boost::python::converter::registry::insert(&radishConvert, type_id<Radish>());

This perfectly works, I can get objects from SWIG and pass it to boost::python. The inverse process is still unsolved but is enough for me.

This is the guide I have used to find the solution:
http://wiki.python.org/moin/boost.python/HowTo#SWIG_exposed_C.2B-.2B-_object_from_Python

泅渡 2024-12-19 02:58:55

该错误来自 Boost.Python。 BP 的类型表中没有 Radish 的条目。如果没有条目,BP 就无法知道该做什么。获得条目的唯一方法是将Radish 包装在BP 中。

我担心 BP 和 SWIG 根本就不适合一起工作,并且非常怀疑您能否让它们按照您想要的方式工作,而无需进行大量的黑客攻击。

我建议您将整个系统移至一个库或另一个库

That error comes from Boost.Python. BP's type table has no entry for Radish. Without an entry, there is no way for BP to know what to do. The only way to get an entry is to wrap Radish in BP.

I am afraid that BP and SWIG were simply not made to work together, and a very much doubt that you will get them to work the way you want, with out extensive hacking.

I recommend that you move your entire system to either one library, or the other

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文