在c++中捕捉Python异常
Catching a Python exception in C++
我正在开发一个服务器-客户端应用程序,其中客户端调用服务器的API,该API为用户输入提供Python接口。这意味着客户端接口和服务器接口是用Python编写的,而套接字代码是用c++编写的。
服务器端:-
我有一个类,Test
,在c++中,这个类是在Python中继承的,名为TestPython,使用SWIG的导演功能。我也有一个异常类MyException在c++。
现在TestPython类的一个函数从Python代码抛出MyException()
。
我想在c++代码中使用SWIG处理从Python抛出的异常。
下面是代码片段: c++代码——class MyException
{
public:
string errMsg;
MyException();
MyException(string);
~MyException();
};
class Test
{
int value;
public:
void TestException(int val);
Test(int);
};
Python代码
class TestPython(Test):
def __init__(self):
Test.__init__(self)
def TestException(self,val):
if val > 20:
throw MyException("MyException : Value Exceeded !!!")
else:
print "Value passed = ",val
现在,如果调用TestException()
函数,它应该抛出MyException
。我想在我的c++代码中处理这个MyException()
异常。
所以谁能建议我如何做到这一点,我的意思是我应该写什么在我的*. I(接口)文件来处理这个
上面用Python编写的TestException()
是由客户端调用的,所以如果服务器抛出任何异常,我必须通知客户端。
要做到这一点,你基本上需要编写一个%feature("director:except")
,它可以处理Python异常并将其作为c++异常重新抛出。下面是一个小而完整的例子:
假设我们有以下想要换行的头文件:
#include <iostream>
#include <exception>
class MyException : public std::exception {
};
class AnotherException : public std::exception {
};
class Callback {
public:
virtual ~Callback() { std::cout << "~Callback()" << std:: endl; }
virtual void run() { std::cout << "Callback::run()" << std::endl; }
};
inline void call(Callback *callback) { if (callback) callback->run(); }
和使用它的Python代码:
import example
class PyCallback(example.Callback):
def __init__(self):
example.Callback.__init__(self)
def run(self):
print("PyCallback.run()")
raise example.MyException()
callback = PyCallback()
example.call(callback)
我们可以定义以下SWIG接口文件:
%module(directors="1") example
%{
#include "example.h"
%}
%include "std_string.i"
%include "std_except.i"
%include "pyabc.i"
// Python requires that anything we raise inherits from this
%pythonabc(MyException, Exception);
%feature("director:except") {
PyObject *etype = $error;
if (etype != NULL) {
PyObject *obj, *trace;
PyErr_Fetch(&etype, &obj, &trace);
Py_DecRef(etype);
Py_DecRef(trace);
// Not too sure if I need to call Py_DecRef for obj
void *ptr;
int res = SWIG_ConvertPtr(obj, &ptr, SWIGTYPE_p_MyException, 0);
if (SWIG_IsOK(res) && ptr) {
MyException *e = reinterpret_cast< MyException * >(ptr);
// Throw by pointer (Yucky!)
throw e;
}
res = SWIG_ConvertPtr(obj, &ptr, SWIGTYPE_p_AnotherException, 0);
if (SWIG_IsOK(res) && ptr) {
AnotherException *e = reinterpret_cast< AnotherException * >(ptr);
throw e;
}
throw Swig::DirectorMethodException();
}
}
%feature("director") Callback;
%include "example.h"
处理一个错误从导演调用,看看它是否是我们的MyException
实例之一,然后重新抛出指针,如果它是。如果你有多种类型的异常被抛出,那么你可能需要使用PyErr_ExceptionMatches
来确定它是什么类型的。
也可以通过值或引用抛出:
// Throw by value (after a copy!)
MyException temp = *e;
if (SWIG_IsNewObj(res))
delete e;
throw temp;
但请注意,如果你在Python中抛出MyException
的子类,这将与对象切片问题发生冲突。
我不太确定代码是否100%正确-特别是我认为引用计数是正确的,但我可能错了。
注意:为了使这个例子工作(%pythonabc
不会工作否则),我不得不调用SWIG与-py3
。这反过来意味着我必须升级到SWIG 2.0,因为我安装的Python 3.2副本已经从SWIG 1.3.40调用的C-API中删除了一些已弃用的函数。
- 如何通过 pybind11 从 python 中的C++中捕获异常?
- Windows错误:异常:使用从C++到Python的ctypes创建DLL时出现访问冲突或Windows错误193
- 析构函数中的互斥锁C++在 Python 中调用 exit() 时会导致异常
- Python Director 类中的 Swig 异常
- C/C++ 未生成 Python 异常回溯
- Cython -Python异常传播C 例外
- 包含python.h和boost/python.hpp的C++导致SEH异常
- 将异常处理从 python 转换为 C++
- Python 子进程异常处理
- Boost.Python自定义异常类
- 为什么 Python 没有捕获C++中引发的异常?
- 如何使c++像python一样给出详细的异常信息
- 在c++中捕捉Python异常
- Python输入和异常vs. c++
- 将内嵌Python异常传播到c++
- Python异常:在调试支持stl的c++代码时,索引超出范围
- 如何通过boost::python捕获python站点的自定义异常
- Java, c++, Python中的异常模型
- 使用SWIG动态地将自定义C++异常重新考虑为Python异常
- 为什么我丢失异常与SWIG, c++, python