With directors routing method calls to Python, and proxies routing them to C++, the handling of exceptions is an important concern. By default, the directors ignore exceptions that occur during method calls that are resolved in Python. To handle such exceptions correctly, it is necessary to temporarily translate them into C++ exceptions. This can be done with the %feature("director:except") directive. The following code should suffice in most cases:
This code will check the Python error state after each method call from a director into Python, and throw a C++ exception if an error occurred. This exception can be caught in C++ to implement an error handler. Currently no information about the Python error is stored in the Swig::DirectorMethodException object, but this will likely change in the future.
It may be the case that a method call originates in Python, travels up to C++ through a proxy class, and then back into Python via a director method. If an exception occurs in Python at this point, it would be nice for that exception to find its way back to the original caller. This can be done by combining a normal %exception directive with the director:except handler shown above. Here is an example of a suitable exception handler:
^{pr2}$
The class Swig::DirectorException used in this example is actually a base class of Swig::DirectorMethodException, so it will trap this exception. Because the Python error state is still set when Swig::DirectorMethodException is thrown, Python will register the exception as soon as the C wrapper function returns.
示例
下面是一个test.i的示例,它说明了该技术:
%module test
%module(directors="1") test
%feature("director");
%feature("director:except") {
if ($error != NULL) {
throw Swig::DirectorMethodException();
}
}
%exception {
try { $action }
catch (Swig::DirectorException &e) { SWIG_fail; }
}
%inline %{
class MyError {
int m_n;
public:
MyError(int n = 0) : m_n(n) {}
~MyError() {}
int get() const { return m_n; }
};
class Demo {
public:
Demo() {}
virtual ~Demo() {}
virtual MyError test() { return MyError(5); }
};
int func(Demo* d) { return d->test().get(); }
%}
在刷和编译之后,一个演示:
>>> import test
>>> d=test.Demo() # default class implementation
>>> test.func(d) # Call virtual method in a C++ test function.
5
以上工作正常。以下覆盖错误:
>>> class Demo2(test.Demo): # New class
... def test(self): # Override virtual function
... return 7 # But don't return a MyError object.
...
>>> d=Demo2()
>>> test.func(d)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: SWIG director type mismatch in output value of type 'MyError'
Section 36.5.4 Exception unrolling在SWIG文档中:
^{pr2}$示例
下面是一个
test.i
的示例,它说明了该技术:在刷和编译之后,一个演示:
以上工作正常。以下覆盖错误:
它捕获了异常并返回了一个有用的异常。以下正确覆盖:
相关问题 更多 >
编程相关推荐