2012-01-13 34 views
1

我使用SWIG和Numpy。我定義了一個名爲inplace()的C函數來快速處理數據數組,並且我想做一些錯誤檢查(如果兩個數組具有相同的維數)。%在swig中重命名和%inline,錯誤檢查

我在.i文件中使用%rename%inline。據我所知,重命名映射函數名稱',所以每次有人使用inplacesafe_inplace運行並檢查錯誤。 。

但它不工作:(據我注意到,不執行safe_inplace,蟒蛇直接inplace運行,而無需觸摸功能的安全版本

# .i 

%include "inplace.h" 
%rename (inplace) safe_inplace; 

%inline %{ 
    void safe_inplace(int* datain, int in_dx, int in_dy, int in_dz, 
         int* dataout, int out_dx, int out_dy) 
    { 
     if ((in_dx != out_dx) || (in_dy != out_dy)) { 
      PyErr_Format(PyExc_ValueError, /*... messgage*/) 
      return; 
     } 

     inplace(/* .. pass the arguments to original function*/); 
    } 

頭文件:

# .h 

void inplace(int* datain, int in_dx, int in_dy, int in_dz, int* dataout, int out_dx, int out_dy); 

的Python:

#.py 
inplace.inplace(a,b) 

原始示例,我修改ç被發現here

回答

3

您的原始方法很接近,但您可能想讓SWIG不要包裝原始版本的功能。

我已經整理了一個稍微簡單一些的例子,說明這可以如何工作。由於頭文件:

void foo(); 

我們希望把它包起來,使得一個稍微修改版本調用真正的人之前調用。

要做到這一點,最簡單的方法是將從未實際上顯示痛飲頭文件在所有的包裝,僅用於編譯的包裝,如:

%module test 

%{ 
#include "test.h" 
#include <iostream> 
%} 

%rename (foo) foo_safe; 
%inline %{ 
    void foo_safe() { 
    std::cout << "Hello world" << std::endl; 
    foo(); // Calls the foo() from test.h, as you'd hope 
    } 
%} 

如果你不想放棄在%include(例如,有你關心在頭文件太多其他的東西),你可以這樣做:

%module test 

%{ 
#include "test.h" 
#include <iostream> 
%} 

%rename (unsafe_foo) foo;  
%include "test.h" 

%rename (foo) foo_safe;  
%inline %{ 
    void foo_safe() { 
    std::cout << "Hello world" << std::endl; 
    foo(); 
    } 
%} 

爲了揭露真正落實foounsafe_foo

或者你可以使用%ignore如果沒有理由的Python用戶能夠調用unsafe_ignore以往任何時候都:

%module test 

%{ 
#include "test.h" 
#include <iostream> 
%} 

%rename (foo) foo_safe;  
%inline %{ 
    void foo_safe() { 
    std::cout << "Hello world" << std::endl; 
    foo(); 
    } 
%} 

%ignore foo;  
%include "test.h" 

最後它看起來像你的目標其實只是之前的呼叫運行一些代碼真正的C函數。如果是這樣的情況下,有幾個方法可以做到這一點,例如真正的函數調用之前,你可以添加Python代碼與pythonprepend

%feature("pythonprepend") foo() %{ 
    print "hello world" 
    # check args and raise possibly 
%} 

或者最後你可能得使用%exception功能,像(未經測試):

%exception inplace { 
    // Check args and possibly throw 
    $action 
} 

$action將被真實呼叫自動替換。

+0

謝謝!這裏的問題:爲什麼在'unsafe_foo'的例子中包含兩次'test.h'?不,這意味着'foo'既可以作爲'foo'又可以作爲'unsafe_foo'(開銷)? – 2012-01-13 10:17:56

+0

@JakubM。 nope,它不會在那裏出現兩次,一個'#include',在一個'%{''%}'對內,另一個是'%include'。後者告訴SWIG將文件的內容導入.i文件(與C或C++中的#include完全相同)。前者告訴SWIG,生成的包裝文件(本例中爲test_wrap.cxx)需要逐字地包含該確切代碼,也就是說test_wrap.cxx將包含確切的'#include',否則''% {%}'對SWIG本身沒有影響。 – Flexo 2012-01-13 10:27:22