python - Python 导演类中的 Swig 异常

标签 python c++ exception swig

我正在使用 Python 中的 Swig Controller 包装一些类。 我的每个类方法都返回一个 MyError 类。发生的事情是,一旦我从我的一个 C++ 派生了一个 python 类并且我忘记返回 MyError() 对象但是我返回 None of "pass"或者我忘记返回任何东西,我的软件在 MyError 的默认构造函数中崩溃通过读取访问冲突类,我无法通过 try/catch block 跟踪此异常。

Swig 中处理此类情况的正确方法是什么?

谢谢!

最佳答案

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:

%exception {
    try { $action }
    catch (Swig::DirectorException &e) { SWIG_fail; }
}

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(); }
%}

swiging和编译后,一个演示:

>>> 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

关于python - Python 导演类中的 Swig 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55489154/

相关文章:

java - 捕获并抛出异常 : What happens "under the hood"?

python - 如何使用Python查找any()中的匹配项?

python - 在 Python 中采样截断的整数幂律?

c++ - UE4 iTween C++ 抛出 "this was nullptr"

c++ - 使用 int [] 运算符的 3D 数组 C++

c++ - 如何正确使用Constructor-Function-Try-Block?

python - MySQLdb 和 Python 3.X

python - 使用 pyInstaller 创建一个使用 UAC 的 exe

c++ - 比较 AES 与 MD4 或其他

java - 套接字异常 : Connection reset after reconnect