Reputation: 1006
I have the following C function which I'm trying to SWIG-ify:
void GetAttOrder(int node, DCE_ORDER order, float att[3]);
which I want to call in Python and access via:
node = 0; order = DCD_TYPR;
attitude = GetAttOrder(node, order);
attitude[0] // 45.232
Where I've previously implemented the DCE_ORDER type as
typedef enum
{
DCD_TPYR = 0,
DCD_TYPR,
DCD_TYRP,
...
DCD_PRYT
} DCE_ORDER;
I've found some documentation on similar problems in the SWIG documentation, but I haven't had any luck implementing a solution. I've also looked into some other stackoverflow questions (this one seems suspiciously close), also to no avail. I suspect that I should use a typemap here, but am young and foolish when it comes to SWIG.
Any suggestions or pointers?
Many thanks.
Upvotes: 1
Views: 532
Reputation: 1006
Ended up solving this a couple days later. If you have a vector that you want to get out you can do something like:
%typemap(in, numinputs=0) float vec3out[3] (float temp[3]) {
$1 = temp;
}
%typemap(argout) float vec3out[3] {
int i;
$result = PyList_New(3);
for (i = 0; i < 3; i++) {
PyObject *o = PyFloat_FromDouble((double) $1[i]);
PyList_SetItem($result,i,o);
}
}
And then can access this function through Python as I requested above. Additionally, if you have another function that you want to pass a list into (a getter/setter pair of functions), you can use the following code:
%typemap(in) float vec3in[3] (float temp[3]) {
int i;
if (!PySequence_Check($input)) {
PyErr_SetString(PyExc_ValueError,"Expected a sequence");
return NULL;
}
if (PySequence_Length($input) != 3) {
PyErr_SetString(PyExc_ValueError,"Size mismatch. Expected 3 elements");
return NULL;
}
for (i = 0; i < 3; i++) {
PyObject *o = PySequence_GetItem($input,i);
if (PyNumber_Check(o)) {
temp[i] = (float) PyFloat_AsDouble(o);
} else {
PyErr_SetString(PyExc_ValueError,"Sequence elements must be numbers");
return NULL;
}
}
$1 = temp;
}
which would allow you to pass in a list.
Upvotes: 2