在 Python 中,如何使用 C++通过 ** 参数返回分配的结构数组的函数?

发布于 2024-09-02 12:33:25 字数 1451 浏览 8 评论 0原文

我想在 Python 工具中使用一些现有的 C++ 代码 NvTriStrip

SWIG 可以轻松处理具有简单参数的函数,但主函数 GenerateStrips 则要复杂得多。

我需要在 SWIG 接口文件中添加什么来指示 primGroups 实际上是一个输出参数并且必须使用 delete[] 清除它?

///////////////////////////////////////////////////////////////////////////
// GenerateStrips()
//
// in_indices: input index list, the indices you would use to render
// in_numIndices: number of entries in in_indices
// primGroups: array of optimized/stripified PrimitiveGroups
// numGroups: number of groups returned
//
// Be sure to call delete[] on the returned primGroups to avoid leaking mem
//
bool GenerateStrips( const unsigned short* in_indices,
                     const unsigned int    in_numIndices,
                     PrimitiveGroup**      primGroups,
                     unsigned short*       numGroups,
                     bool                  validateEnabled = false );

仅供参考,这是 PrimitiveGroup 声明:

enum PrimType
{
    PT_LIST,
    PT_STRIP,
    PT_FAN
};

struct PrimitiveGroup
{
    PrimType type;
    unsigned int numIndices;
    unsigned short* indices;

    PrimitiveGroup() : type(PT_STRIP), numIndices(0), indices(NULL) {}
    ~PrimitiveGroup()
    {
        if(indices)
            delete[] indices;
        indices = NULL;
    }
};

I'd like to use some existing C++ code, NvTriStrip, in a Python tool.

SWIG easily handles the functions with simple parameters, but the main function, GenerateStrips, is much more complicated.

What do I need to put in the SWIG interface file to indicate that primGroups is really an output parameter and that it must be cleaned up with delete[]?

///////////////////////////////////////////////////////////////////////////
// GenerateStrips()
//
// in_indices: input index list, the indices you would use to render
// in_numIndices: number of entries in in_indices
// primGroups: array of optimized/stripified PrimitiveGroups
// numGroups: number of groups returned
//
// Be sure to call delete[] on the returned primGroups to avoid leaking mem
//
bool GenerateStrips( const unsigned short* in_indices,
                     const unsigned int    in_numIndices,
                     PrimitiveGroup**      primGroups,
                     unsigned short*       numGroups,
                     bool                  validateEnabled = false );

FYI, here is the PrimitiveGroup declaration:

enum PrimType
{
    PT_LIST,
    PT_STRIP,
    PT_FAN
};

struct PrimitiveGroup
{
    PrimType type;
    unsigned int numIndices;
    unsigned short* indices;

    PrimitiveGroup() : type(PT_STRIP), numIndices(0), indices(NULL) {}
    ~PrimitiveGroup()
    {
        if(indices)
            delete[] indices;
        indices = NULL;
    }
};

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

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

发布评论

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

评论(3

挽清梦 2024-09-09 12:33:25

您是否看过 SWIG 有关“cpointer.i”和“carray.i”库的文档?它们可以在此处找到。这就是您必须操纵事物的方式,除非您想创建自己的实用程序库来伴随包装的代码。以下是 Python 使用 SWIG 处理指针的链接。

关于让它识别输入与输出的问题。他们在文档这里中有另一节,它准确地描述了那。您可以在 *.i 文件中标记 OUTPUT 内容。因此,在您的情况下,您可以编写:

%inline{
extern bool GenerateStrips( const unsigned short* in_dices,
                            const unsigned short* in_numIndices,
                            PrimitiveGroup** OUTPUT,
                            unsigned short* numGroups,
                            bool validated );
%}

它为您提供了一个函数,该函数将 bool 和 PrimitiveGroup* 数组作为元组返回。

这有帮助吗?

Have you looked at the documentation of SWIG regarding their "cpointer.i" and "carray.i" libraries? They're found here. That's how you have to manipulate things unless you want to create your own utility libraries to accompany the wrapped code. Here's the link to the Python handling of pointers with SWIG.

Onto your question on getting it to recognize input versus output. They've got another section in the documentation here, that describes exactly that. You lable things OUTPUT in the *.i file. So in your case you'd write:

%inline{
extern bool GenerateStrips( const unsigned short* in_dices,
                            const unsigned short* in_numIndices,
                            PrimitiveGroup** OUTPUT,
                            unsigned short* numGroups,
                            bool validated );
%}

which gives you a function that returns both the bool and the PrimitiveGroup* array as a tuple.

Does that help?

爱你不解释 2024-09-09 12:33:25

实际上,直接为事物创建 python 绑定非常容易,我不知道为什么人们会为像 SWIG 这样令人困惑的包装器东西而烦恼。

只需对外部数组的每个元素使用 Py_BuildValue 一次,每行生成一个元组。将这些元组存储在 C 数组中。然后调用 PyList_NewPyList_SetSlice 生成元组列表,并从 C 函数返回列表指针。

It's actually so easy to make python bindings for things directly that I don't know why people bother with confusing wrapper stuff like SWIG.

Just use Py_BuildValue once per element of the outer array, producing one tuple per row. Store those tuples in a C array. Then Call PyList_New and PyList_SetSlice to generate a list of tuples, and return the list pointer from your C function.

裸钻 2024-09-09 12:33:25

我不知道如何使用 SWIG 来做到这一点,但您可能需要考虑转向更现代的绑定系统,例如 PyrexCython

例如,对于此类情况,Pyrex 使您可以访问 C++ 删除。以下是文档的摘录:

处置

del 语句可以应用于指向 C++ 结构体的指针
解除分配它。这相当于 C++ 中的删除。

cdef 灌木 *big_sh
big_sh = 新灌木丛(42.0)
display_in_garden_show(big_sh)
德尔大_sh

http://www. cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/version/Doc/Manual/using_with_c++.html

I don't know how to do it with SWIG, but you might want to consider moving to a more modern binding system like Pyrex or Cython.

For example, Pyrex gives you access to C++ delete for cases like this. Here's an excerpt from the documentation:

Disposal

The del statement can be applied to a pointer to a C++ struct
to deallocate it. This is equivalent to delete in C++.

cdef Shrubbery *big_sh
big_sh = new Shrubbery(42.0)
display_in_garden_show(big_sh)
del big_sh

http://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/version/Doc/Manual/using_with_c++.html

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