尝试包装二进制库,其中头文件定义typedef struct x x_t
,其中尚未定义struct x。如何定义一个接口文件,允许python在下面定义的函数中使用类型defed结构。
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'
答案 0 :(得分:1)
由于Python不支持输出参数,因此典型的方法是创建一组压缩必须传递输出参数的类型映射,而是在内部使用附加到返回值的临时值。这是一个将句柄转换为Python整数对象的最小例子:
%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));
%}
第一个typemap将Python整数转换为myConnectionHandle
,以用作函数的输入。
第二个typemap告诉SWIG在输入时忽略myConnectionHandle*
,因为它是一个输出参数,在调用函数时只需使用临时值来存储句柄。
第三个typemap告诉SWIG将返回的句柄值附加到返回结果,必要时将其转换为[retval, handle]
列表。
以下是使用myconnection.h
的示例,但我添加了一个函数来将句柄作为输入,并添加了函数的一些虚拟实现以使其进行编译。
%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"
输出:
>>> import myconnection
>>> retval, handle = myconnection.myConnectionOpen('foo','bar')
>>> myconnection.useConnection(handle)
>>>