2012-07-27 68 views
3

我有一個全局變量數組,我想拉入python。而我在與varout類型映射的困難:用swig和python擴展全局c變量數組

/* example.c */ 
int foo[] = {0, 1}; 

,這裏是非常香草接口:

/* example.i */ 
%module example 
%{  
extern int foo[2]; 
%} 

%typemap(varout) int foo[] { 
    int i; 
    //$1, $1_dim0, $1_dim1 
    $result = PyList_New($1_dim0); 
    for (i = 0; i < $1_dim0; i++) { 
    PyObject *o = PyInt_FromLong((double) $1[i]); 
    PyList_SetItem($result,i,o); 
    } 
} 

%include "example.c" 

當我嘗試用下面的SConstruct構建它:

import distutils.sysconfig 
env = Environment(SWIGFLAGS='-python -shadow -Wall'.split(), 
        CPPPATH=[distutils.sysconfig.get_python_inc()], 
        SHLIBPREFIX="") 
env.SharedLibrary('_example.so', ['example.c', 'example.i']) 

$1_dim0特殊變量未填充,導致在example_wrap.c中產生以下非編譯代碼:

SWIGINTERN PyObject *Swig_var_foo_get(void) { 
    PyObject *pyobj = 0; 

    { 
    int i; 
    //foo, , foo_dim1 
    pyobj = PyList_New(); 
    for (i = 0; i < ; i++) { 
     PyObject *o = PyInt_FromLong((double) foo[i]); 
     PyList_SetItem(pyobj,i,o); 
    } 
    } 
    return pyobj; 
} 

所以很明顯,typemap匹配已經發生,但是數組的維數缺失。我錯過了什麼?硬編碼的維度確實有用。

一般來說,有什麼辦法可以用swig來擴展全局cvar變量嗎?

$ swig -version 
SWIG Version 2.0.4 
Compiled with g++ [i686-pc-linux-gnu] 
Configured options: +pcre 
Please see http://www.swig.org for reporting bugs and further information 
+0

我展示瞭如何讓你的榜樣工作,但我有點不清楚什麼你的意思是:*「一般來說,有什麼方法可以用swig擴展全局cvar變量嗎?」* - 除了修改typemap之外,還有更多嗎? – Flexo 2012-07-27 21:02:34

+0

我想知道是否可以用'__getitem __()'擴展'foo'變量類型,使其可以用[]編寫腳本。 – Oleksiy 2012-07-27 23:02:35

+0

不是PyList已經可以下載嗎? – Flexo 2012-07-28 09:33:46

回答

2

就快與你的varout類型映射。你需要做兩個小的改動:

  1. 你需要的大小ANY添加到int foo[]類型映射:

    %typemap(varout) int foo[ANY] { 
        int i; 
        //$1, $1_dim0, $1_dim1 
        $result = PyList_New($1_dim0); 
        for (i = 0; i < $1_dim0; i++) { 
        PyObject *o = PyInt_FromLong((double) $1[i]); 
        PyList_SetItem($result,i,o); 
        } 
    } 
    

    這可以確保您的類型映射爲(任何)已知大小的數組匹配,不僅僅相當於int *foo

  2. 您需要修改example.c以使foo的大小更清晰。這是合法和正確的C,但如果不是一個完整的C編譯器,推導出該數組的大小會非常棘手。它更改爲:

    int foo[2] = {0, 1}; 
    

    足以確保它的varout類型映射相匹配。

有了這兩個變化生成的代碼可以作爲你希望:

SWIGINTERN PyObject *Swig_var_foo_get(void) { 
    PyObject *pyobj = 0; 

    { 
    int i; 
    //foo, 2, foo_dim1 
    pyobj = PyList_New(2); 
    for (i = 0; i < 2; i++) { 
     PyObject *o = PyInt_FromLong((double) foo[i]); 
     PyList_SetItem(pyobj,i,o); 
    } 
    } 
    return pyobj; 
} 

是什麼得到我的機器上生成的這些變化。

0

對於那些像我這樣誰思考做什麼用的非簡單類型的數組 - 在這裏是做這件事:

非簡單類型:

typedef struct { 
    int a; 
    float b; 
} Foo; 

和一個全局數組:

extern Foo *foov[40]; 

%typemap(varout) Foo *foov[ANY] { 
    int i; 
    $result = PyList_New($1_dim0); 
    for (i = 0; i < $1_dim0; i++) { 
     PyObject *o = SWIG_NewPointerObj($1[i], SWIGTYPE_p_Foo, 0); 
     PyList_SetItem($result, i, o); 
    } 
} 

就分享了這個,因爲我花了永遠找出來,這篇文章幫助。只需要找出如何分配我的非簡單類型的夜風版本 - 發現埋在這裏:

http://www.swig.org/Doc2.0/Python.html#Python_nn64