【问题标题】:SWIG, Python, C with void return arguments带有 void 返回参数的 SWIG、Python、C
【发布时间】:2012-07-10 11:57:07
【问题描述】:

我在 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 接口文件中实现这一点。我已经将typemaps.i 用于其他类型的指针返回参数,但它似乎不支持void*

【问题讨论】:

    标签: python c swig void-pointers


    【解决方案1】:

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

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

    痛饮 -python -Wall test.i gcc -fPIC -I/usr/include/python2.7 test_wrap.c -shared -o _test.so -Wall -Wextra LD_LIBRARY_PATH=。 python2.7运行.py

    它给出了以下输出:

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

    因为这里的“数组”只是一个用calloc 在 C 中分配的真实内存块的代理,所以您对数组所做的任何更改都将在您下次读取它时从 Python 中可见。


    如果您使用%array_class 而不是%array_functions,Python 代码将变为:

    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 一样)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-16
      • 2017-07-13
      • 1970-01-01
      • 1970-01-01
      • 2016-05-09
      • 1970-01-01
      • 2019-01-28
      • 1970-01-01
      相关资源
      最近更新 更多