gpt4 book ai didi

Swig 包装 typedef 结构

转载 作者:行者123 更新时间:2023-12-02 03:31:19 26 4
gpt4 key购买 nike

试图包装一个二进制库,其中头文件定义了 typedef struct x x_t其中 struct x 尚未定义。我如何定义一个接口(interface)文件,允许 python 在下面定义的函数中使用类型定义的结构。

我的连接.h

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);

我的连接.i
% module myconnection
%{
#include "myconnection.h"
%}

%include "myconnection.h"

工作 C/C++ 代码示例
myConnectionHandle chandle;
myConnectionError error;
error = myConnectionOpen("foo","bar",&chandle);

预期的 Python 代码
import myconnection
handle = myconnection.myConnectionHandle
err = myconnection.myConnectionOpen("foo","1080",handle)

Python 结果
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'

最佳答案

由于 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));
%}

第一个类型映射将 Python 整数转换为 myConnectionHandle用作函数的输入。

第二个类型图告诉 SWIG 忽略 myConnectionHandle*在输入上,因为它是一个输出参数,并且在调用函数时只使用一个临时值来存储句柄。

第三个类型映射告诉 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)
>>>

关于Swig 包装 typedef 结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26567457/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com