|
From: Bob H. <bob...@gm...> - 2008-01-14 06:46:50
|
I dug through the doco and maillist archive for a few hours but I'm still
stuck. It seems to me that this should be a fairly simple thing to do, but
...
I have a function in a shared library libfoo.so defined with foo.h:
foo.h:
typedef struct foo_st FOO;
int foo_init(FOO **foo); /* malloc memory for structure */
int foo_use(FOO *foo); /* do something with the structure */
int foo_fini(FOO *foo); /* free up the structure */
... that I would normally call from C like this:
FOO *foo = NULL;
int status = 0;
status = foo_init(&foo);
...
foo_use(foo); /* etc */
foo_fini(foo);
... ie a fairly typical abstract opaque data structure
When I swig this with the following simple foo.i file:
%module foo
%{
#include "foo.h"
%}
%include "foo.h"
... I get python errors:
import foo
foo.foo_init ()
=>
foo.foo_init()
TypeError: foo_init() takes exactly 1 argument (0 given)
.. which is understandable, but how do I give it an abstract pointer? This
also fails:
import foo
my_foo = foo.FOO ()
foo.foo_init(my_foo)
=>
my_foo = foo.FOO()
AttributeError: 'module' object has no attribute 'FOO'
I _had _thought that I could %typemap the need for an argument out of it
with this (scoured from the doco):
%module foo
%include "typemaps.i"
%typemap(argout) FOO **foo {
PyObject *o, *o2, *o3;
o = PyLong_FromVoidPtr(*$1);
if ((!$result) || ($result == Py_None)) {
$result = o;
} else {
if (!PyTuple_Check($result)) {
PyObject *o2 = $result;
$result = PyTuple_New(1);
PyTuple_SetItem($result,0,o2);
}
o3 = PyTuple_New(1);
PyTuple_SetItem(o3,0,o);
o2 = $result;
$result = PySequence_Concat(o2,o3);
Py_DECREF(o2);
Py_DECREF(o3);
}
}
%{
#include "foo.h"
%}
%include " foo.h"
... but it gives exactly the same errors.
Any ideas out there?
For completeness, here's the build chain that I used:
cc -c foo.c
ld -shared -o libfoo.so foo.o
swig -python foo.i
cc -c foo_wrap.c -I /usr/include/python2.5
ld -shared -rpath "`pwd`" -o _foo.so foo_wrap.o libfoo.so
And the source code foo.c:
struct foo_st {
int i;
int b;
};
#include "foo.h"
#include "malloc.h"
#define FOO_SIZE 10
int foo_init(FOO **foo)
{
*foo = malloc(FOO_SIZE);
return(0);
}
int foo_use(FOO *foo)
{
foo->i = 1;
return(0);
}
int foo_fini(FOO *foo)
{
free(foo);
return(0);
}
|