2013-12-20 26 views
2

我使用SWIG將C庫封裝到python模塊。但例外似乎沒有在正確的地方要提高,我對此有一個簡單的演示,PyErr_SetString不立即引發異常(Swig)?

except_test.i

%module except_test 


%{ 
#include "except_test.h" 
#include <stdio.h> 
%} 

%{ 
static int flagged_exception = 0; 

void throw_except() 
{ 
    flagged_exception = 1; 
    printf("flag set \n"); 
} 
%} 

%exception { 
    $action 
    printf("exception block\n"); 
    if (flagged_exception) { 
     printf("before setstring\n"); 
     PyErr_SetString(PyExc_RuntimeError, "test except"); 
     printf("after setstring\n"); 
     flagged_exception = 0; 
    } 
} 
%include "except_test.h" 

except_test.c

#include "except_test.h" 


int except_test(int a) { 

    if (a < 0) { 
     throw_except(); 
     return 0; 
    } else{ 
     return -1; 
    } 
} 

run_except.py

from except_test import * 
import time 

def test(): 
    b = except_test(-1) 
    print 'b=', b 

try: 
    test() 
except: 
    print "caught exception" 

for i in range(10): 
    print i 
    time.sleep(1) 

現在,如果我跑run_except.py

$python run_except.py 
flag set 
exception block 
before setstring 
after setstring 
b= 0 
0 
Traceback (most recent call last): 
    File "run_except.py", line 15, in <module> 
    time.sleep(1) 
RuntimeError: test except 

作爲輸出顯示,try/catch塊未捕獲異常。 這是爲什麼?以及如何避免這種情況?

感謝,

+0

查看_wrap.c文件中生成的代碼。 %異常中的代碼在那裏? – Schollii

回答

3

你必須從一個Python擴展返回NULL有它立即注意到錯誤:

if (flagged_exception) { 
    PyErr_SetString(PyExc_RuntimeError, "test except"); 
    flagged_exception = 0; 
    return NULL; 
} 

但使用通用痛飲宏將使痛飲接口更容易移植到其他語言。

2

你需要把SWIG_fail;PyErr_SetString之後。或者,有一個方便的(和更重要的語言無關的)宏SWIG_exception(SWIG_RuntimeError, "error message")包裝PyErr_SetStringSWIG_fail