tags:

views:

251

answers:

3

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;
    }
};
+1  A: 

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.

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

Forest
+1  A: 

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?

wheaties
+2  A: 

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.

apenwarr
SWIG is great when you have a huge number of API functions to be wrapped, where most of them only use simple types (int, float, etc.) or use structures in a fairly consistent way. But with a small number of API functions, I agree that the pain of writing the necessary SWIG typemaps probably outweighs the cost of writing the Python bindings by hand.
jchl