簡體   English   中英

SWIG,Python和C,帶有無效的返回參數

[英]SWIG, Python, C with void return arguments

我在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*

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)

我使用以下命令在系統上編譯並運行了它:

swig -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 run.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一樣)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM