gpt4 book ai didi

python - 带有无效返回参数的 SWIG、Python、C

转载 作者:太空宇宙 更新时间:2023-11-04 07:33:13 25 4
gpt4 key购买 nike

我在 C 头文件中有以下函数构造函数:

int my_fun(int i, void *a, void *b, void *c);

为了提供一些上下文,我提供了一个 C 代码实现来说明如何使用它:

int error;
double *a, *b, *c;

int i = 1;
int num = 500;
int num_dim = 2;

a = (double *) calloc(num, sizeof(double));
b = (double *) calloc(num, sizeof(double));
if (num_dim >= 3)
c = (double *) calloc(num, sizeof(double));
else
c = 0

error = my_fun(i,a,b,c);
error = my_fun(i,NULL,b,NULL); /*read only b*/

我想知道如何在 SWIG 接口(interface)文件中实现它。我已经将 typemaps.i 用于其他类型的指针返回参数,但它似乎不支持 void*

最佳答案

SWIG 提供了一个文件,carrays.i这与 calloc 非常匹配。您可以使用宏 %array_functions%array_class 来公开一些将 C 样式数组包装到目标语言的辅助函数。 (即使您使用的是 C,您仍然可以同时使用两者)。我制作了以下界面,它使用 %include 一次包装并定义了一个简单的 my_fun:

%module test

%include "carrays.i"

%array_functions(double,DoubleArray)

%inline %{
int my_fun(int i, void *a, void *b, void *c) {
printf("my_fun: i=%d, a=%p, b=%p, c=%p\n",i,a,b,c);
return 0;
}
%}

如果你想支持更多的类型而不仅仅是 calloc(num, sizeof(double)) 你需要添加更多的 %array_functions 到你的接口(interface)文件。 carrays.i 还生成用于获取和设置数组中的特定值以及删除它们的函数

之后,您的示例在 Python 中的用法如下所示:

import test

i = 5
num = 500
num_dim = 2

a = test.new_DoubleArray(num)
b = test.new_DoubleArray(num)
c = None
if num_dim >= 3:
c = test.new_DoubleArray(num)

error = test.my_fun(i,a,b,c)
error = test.my_fun(i,None,b,None)

# Beware of the exceptions, you need a finally: really
test.delete_DoubleArray(a)
test.delete_DoubleArray(b)
test.delete_DoubleArray(c)

我在我的系统上编译并运行了它:

swig -python -Wall test.i gcc -fPIC -I/usr/include/python2.7 test_wrap.c -shared -o _test.so -Wall -WextraLD_LIBRARY_PATH=. python2.7 run.py

Which gave the following output:

my_fun: i=5, a=0x2767fa0, b=0x2768f50, c=(nil)my_fun: i=5, a=(nil), b=0x2768f50, c=(nil)

Since the "array" here is just a proxy to a real chunk of memory allocated in C with calloc any changes you make to the array will be visible from Python the next time you read it.


If you use %array_class instead of %array_functions the Python code becomes:

import test

i = 5
num = 500
num_dim = 2

a = test.DoubleArray(num)
b = test.DoubleArray(num)
c = None
if num_dim >= 3:
c = test.DoubleArray(num)

error = test.my_fun(i,a.cast(),b.cast(),c.cast() if c else None)
error = test.my_fun(i,None,b.cast(),None)

请注意,这里的引用计数已经消除了显式删除数组的需要,通过推迟引用计数解决了异常问题。 %array_class 还提供了 __getitem____setitem__ 的实现,因此它可以像 Python 中的任何其他数组或容器一样被子脚本化。 (虽然没有边界检查,就像 C 一样)

关于python - 带有无效返回参数的 SWIG、Python、C,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11422945/

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