如何防止Python返回到C++ Boosi::Python::ErrRoRyRead ySt集合?

2024-10-03 09:10:41 发布

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

在提出这个问题之前,我需要说明一些背景。请容忍我。使用boost::python我向python公开了一些异常类型,比如MyExceptionType。我有一个boomTest,我将其公开给Python以检查它是否工作。Python调用boomTest,它正确地处理了MyExceptionType,目前为止还不错。这是C++的一个方面:

static void boomTest() {
    throw MyExceptionType("Smoked too many Cohibas!");
}

static PyObject *myExceptionPtr = NULL;
static void translate(MyExceptionType const &exception) {
    assert(myExceptionPtr != NULL);
    boost::python::object pythonExceptionInstance(exception);
    PyErr_SetObject(myExceptionPtr, pythonExceptionInstance.ptr());
}

BOOST_PYTHON_MODULE(test) {
    class_<MyExceptionType> myException("MyExceptionType", no_init);
    myException.add_property("message", &MyExceptionType::what);
    myExceptionPtr = myException.ptr();
    register_exception_translator<MyExceptionType>(&translate);
}

这就是Python的一面:

^{pr2}$

现在事情变得有点毛茸茸的,因为在一个实际的用例中,我从C++ Boost(非Python)线程中调用了一个Python,如下:

# this is a Python callback invoked from a C++ boost non-Python thread
def handle(future):
    try:
        # future.get() throws MyExceptionType if there was a cluster exception
        "Cluster response received with value: %s" % future.get()

    except MyExceptionType as ex:
        print 'Success! MyExceptionType gracefully handled:' \
            '\n message="%s"' % ex.message

现在,操作

当C++ {CD6>}调用抛出一个用于Python来处理的^ {CD1>}时,为什么我的C++回调触发器会得到^ { }异常?我怀疑这种行为是由于异常被抛出到C++(非Python)线程中的事实。在

强制Python像前面的例子一样处理异常需要什么?在

我尝试过C++中的回调触发器来执行以下操作:

void callbackTrigger() {
    try {
        pythonHandle_(getFuture());
    }
    // why do I get this???
    catch (boost::python::error_already_set&) {
        // this doesn't help, Python doesn't still handle MyExceptionType
        boost::python::handle_exception();
    }
}

Tags: messagegetexceptionstaticfuturethisnulltranslate
1条回答
网友
1楼 · 发布于 2024-10-03 09:10:41

我验证了我关于Python的理论,不喜欢处理抛出的异常(即使在Python代码中),而是作为一个异类C++线程的一部分执行。因此,我构建了这个纯Python包装器来处理主Python线程中的回调。在

import example
reload(example)
from example import MyExceptionType

condition = threading.Condition()
futures = []

# Actual handle executed by the main Python THREAD
# __after__ submitting all the jobs to the Cluster
# N is the number of jobs that were submitted to the Cluster
def handle(N):
    while (N > 0):
        condition.acquire()
        try:
            # wait for max of a second to prevent this thread waiting indefinitely
            # when it misses notify while being busy processing responses
            condition.wait(1.0)
            for future in futures:
                try:
                    print 'callback received! the response is:\n %s' % future.get()

                except MyExceptionType as ex:
                    print 'MyExceptionType gracefully handled:' \
                          '\n message="%s"' % ex.message
                except:
                    print 'Caught unhandled exception: %s "%s"' % (sys.exc_info()[0], sys.exc_info()[1])
        finally:
            N -= len(futures)
            del(futures[:])
            condition.release()

# callback called from a C++ boost THREAD
def callback(future):
    condition.acquire()
    try:
        # do not consume the future here, rather let the main 
        # Python thread deal with it ...
        futures.append(future)
        condition.notify()
    finally:
        condition.release()

虽然不理想,但工作正常,输出正确:

^{pr2}$

相关问题 更多 >