Trying to wrap a binary library where the headerfile defines a typedef struct x x_t
where struct x has not been defined. How can i define a interface file that allows python to use the type defed structure in the Functions defined below.
typedef int myConnectionError;
// Note: this struct does not exist
// The typedef is done to strengthen type checking
typedef struct _myConnectionHandle* myConnectionHandle;
myConnectionError myConnectionOpen( const char *x , const char *y , myConnectionHandle *hand);
% module myconnection
%{
#include "myconnection.h"
%}
%include "myconnection.h"
myConnectionHandle chandle;
myConnectionError error;
error = myConnectionOpen("foo","bar",&chandle);
import myconnection
handle = myconnection.myConnectionHandle
err = myconnection.myConnectionOpen("foo","1080",handle)
Python 2.6.6 (r266:84292, Jan 22 2014, 09:42:36)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import myconnection
>>> handle = myconnection.myConnectionHandle()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'myConnectionnHandle'
Since Python doesn't support output parameters, the typical way is to create a set of typemaps that suppress having to pass an output parameter and instead use a temporary value internally that is appended to the return value. Here's a minimal example that converts the handles to and from Python integer objects:
%typemap(in) myConnectionHandle %{
$1 = (myConnectionHandle)PyLong_AsVoidPtr($input);
%}
%typemap(in,numinputs=0) myConnectionHandle* (void* tmp) %{
$1 = (myConnectionHandle*)&tmp;
%}
%typemap(argout) myConnectionHandle* %{
$result = SWIG_Python_AppendOutput($result,PyLong_FromVoidPtr(*$1));
%}
The first typemap converts a Python integer to a myConnectionHandle
to be used as an input to a function.
The second typemap tells SWIG to ignore myConnectionHandle*
on input since it is an output parameter, and just use a temporary value to store the handle in when calling the function.
The third typemap tells SWIG to append the returned handle value to the return result, converting it to a list of [retval, handle]
if necessary.
Here's an example using your myconnection.h
but I added a function to take a handle as input as well and added some dummy implementation of the functions to get it to compile.
%module myconnection
%{
#include "myconnection.h"
myConnectionError myConnectionOpen( const char *x , const char *y , myConnectionHandle *hand)
{
static int something;
*hand = (myConnectionHandle)&something;
return 0;
}
void useConnection(myConnectionHandle h)
{
}
%}
%typemap(in) myConnectionHandle %{
$1 = (myConnectionHandle)PyLong_AsVoidPtr($input);
%}
%typemap(in,numinputs=0) myConnectionHandle* (void* tmp) %{
$1 = (myConnectionHandle*)&tmp;
%}
%typemap(argout) myConnectionHandle* %{
$result = SWIG_Python_AppendOutput($result,PyLong_FromVoidPtr(*$1));
%}
%include "myconnection.h"
Output:
>>> import myconnection
>>> retval, handle = myconnection.myConnectionOpen('foo','bar')
>>> myconnection.useConnection(handle)
>>>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With