Python director类中的Swig异常

2024-04-24 00:13:46 发布

您现在位置:Python中文网/ 问答频道 /正文

我在Python中使用Swig控制器包装一些类。 我的每个类方法都返回一个MyError类。发生的是,一旦我从我的C++中派生了一个Python类,并且我忘记返回MyReRoR()对象,但是我没有返回“PASS”,或者我忘记返回任何东西,我的软件通过读访问冲突在MyCrror类的默认构造函数中崩溃,并且我不能通过TI/catch块跟踪这个异常。在

在这种情况下,正确的处理方法是什么?在

谢谢!在


Tags: 对象方法软件ti情况pass控制器swig
1条回答
网友
1楼 · 发布于 2024-04-24 00:13:46

Section 36.5.4 Exception unrolling在SWIG文档中:

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:

%feature("director:except") {
    if ($error != NULL) {
        throw Swig::DirectorMethodException();
    }
}

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'

它捕获了异常并返回了一个有用的异常。以下正确覆盖:

>>> class Demo2(test.Demo):
...  def test(self):
...   return test.MyError(7)
...
>>> d=Demo2()
>>> test.func(d)
7

相关问题 更多 >