我在这里忘记了。我期望在C ++中捕获异常,以便我可以将它们映射到python中的自定义异常类。我现在得到的只是python Exceptions。我无法在生成的代码中捕获我的异常???
程序:
#!/usr/bin/python
import os
import sys
import hpsphal_python
prog = os.path.basename(__file__) + ": "
try:
hal = hpsphal_python.System_getSystem()
scs = hal.getStorageClusters()
if len(scs) == 0:
print >>sys.stderr, prog + "No storage clusters found."
os._exit(-1)
for sc in scs:
print "sc: ", sc.getUUID()
conts = sc.getControllers()
for c in conts:
try:
c.setClock()
except hpsphal_python.Exception as e:
print "he: ", e.what()
except RuntimeError as e:
print "rt: ", e, e[0]
except Exception as e:
print "e: ", e, e[0]
os._exit(0)
except Exception, e:
print "E: ", e
os._exit(-1)
输出:
sc: 222367ad-0005-1000-95ab-415a34303736
e: setControllerClock setControllerClock
e: setControllerClock setControllerClock
sc: MXQ04205MV_Con_0_Cluster
e: setControllerClock setControllerClock
C ++中的相同代码实际上捕获了异常:
#include "time.h"
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <exception>
#include <boost/foreach.hpp>
#include <boost/regex.hpp>
#include <boost/thread/thread.hpp>
#include "Exception.hpp"
#include "StorageCluster.hpp"
#include "Controller.hpp"
#include "System.hpp"
using namespace std;
int main (int argc, char *argv[])
{
danAPI::SystemPtr danSystem;
try {
danSystem = danAPI::System::getSystem();
}
catch(danAPI::Exception& e) {
cerr << "Unable to initialize danAPI" << e.what() << endl;
return -1;
}
try {
danAPI::StorageClusterPtrList danStorageClusters = danSystem->getStorageClusters();
BOOST_FOREACH(danAPI::StorageClusterPtr sc, danStorageClusters)
{
danAPI::ControllerPtrList danStorageControllers = sc->getControllers();
BOOST_FOREACH(danAPI::ControllerPtr c, danStorageControllers)
{
try {
c->setClock();
}
catch(danAPI::Exception& e) {
cerr << "HAL Exception: " << e.what() << endl;
}
catch(exception& e) {
cerr << "Standard Exception: " << e.what() << endl;
}
}
}
}
catch(exception& e) {
cerr << "Unable to get storage clusters: " << e.what() << endl;
}
return 0;
}
输出:
HAL Exception: setControllerClock: SetClock exception: function failed (1)
/jenkins/workspace/ts1.4-hpsphal/storage-lib/src/Raptor.cpp: 1100
/jenkins/workspace/ts1.4-hpsphal/storage-lib/src/Raptor.cpp: 791
(1)
/jenkins/workspace/ts1.4-hpsphal/storage-lib/src/StorageCluster_Rcim.cpp: 2158
HAL Exception: setControllerClock: SetClock exception: function failed (1)
/jenkins/workspace/ts1.4-hpsphal/storage-lib/src/Raptor.cpp: 1100
/jenkins/workspace/ts1.4-hpsphal/storage-lib/src/Raptor.cpp: 791
(1)
/jenkins/workspace/ts1.4-hpsphal/storage-lib/src/StorageCluster_Rcim.cpp: 2158
球员:
custom Exception class
SWIG 2.0.12
boost 1.41 throw_exception
我生成的代码中的代码段:
{
try {
(arg1)->setClock();
} catch(danAPI::Exception& e) {
std::cerr << "++++++" << std::endl;
} catch(std::exception& e) {
std::cerr << "++++++" << std::endl;
} catch(boost::exception& e) {
std::cerr << "++++++" << std::endl;
} catch(...) {
std::cerr << "++++++" << std::endl;
}
}
resultobj = SWIG_Py_Void();
return resultobj;
fail:
return NULL;
这是我的.i文件(hdrs宏用我的头文件填充)
%include "stdint.i"
%include "stl.i"
%include "std_string.i"
%include "std_vector.i"
%include "std_string.i"
%include "std_pair.i"
%include "std_set.i"
%include "typemaps.i"
%apply unsigned long long &OUTPUT { unsigned long long &firstCharInBuffer };
%apply unsigned long long &OUTPUT { unsigned long long &nextChar };
%exceptionclass danAPI::Exception;
%exception {
try {
$action
}
catch(danAPI::Exception &e)
{
SWIG_Python_Raise(SWIG_NewPointerObj(
(new danAPI::Exception(static_cast<const danAPI::Exception&>(e))),
SWIGTYPE_p_danAPI__Exception,SWIG_POINTER_OWN),
"Exception", SWIGTYPE_p_danAPI__Exception);
SWIG_fail;
}
}
// need to define the templates for shared_ptr<T> before we define the
// various T's below; put in a common place so the various SWIG interfaces
// stay in sync
%include "hpsphal_ptrs.i"
%{
${hash_public_headers}
using namespace danAPI;
%}
${percent_public_headers}
// need to define the vector types after we've defined the types
// themselves; moved to a common place to keep the various SWIG interfaces
// in sync
%include "hpsphal_vectors.i"
我在gdb中运行了我的代码,“catch throw”。我看到了一些我在库中内部捕获的例外情况。应该有我的库引发的3个异常,然后被我的SWIG代码捕获。
这是内部抓住的:
#0 0x000000337c8bccb0 in __cxa_throw () from /usr/lib64/libstdc++.so.6
#1 0x00007ffff122a1ac in boost::throw_exception<danAPI::Exception> (e=...) at /usr/include/boost/throw_exception.hpp:64
#2 0x00007fffef398841 in danAPI::StorageClusterFactory::getStorageControllerType (this=0x7fffffffd6d0, path="/dev/sg4")
at /home/chchr/src/hpsphal/storage-lib/src/StorageClusterFactory.cpp:247
#3 0x00007fffef398aa8 in danAPI::StorageClusterFactory::createStorageCluster (this=0x7fffffffd6d0, path="/dev/sg4",
storclustpList=std::vector of length 1, capacity 1 = {...}, cluster=std::tr1::shared_ptr (empty) 0x0, err=...)
at /home/chchr/src/hpsphal/storage-lib/src/StorageClusterFactory.cpp:308
#4 0x00007fffef3a262c in boost::_mfi::cmf4<void, danAPI::StorageClusterFactory, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, danAPI::ConstStorageClusterPtrList const&, danAPI::ConstStorageClusterPtr&, boost::exception_ptr&>::call<danAPI::StorageClusterFactory const* const, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<std::tr1::shared_ptr<danAPI::StorageCluster const>, std::allocator<std::tr1::shared_ptr<danAPI::StorageCluster const> > > const, std::tr1::shared_ptr<danAPI::StorageCluster const>, boost::exception_ptr> (this=0x896740, u=@0x896750, b1=
"/dev/sg4", b2=std::vector of length 1, capacity 1 = {...}, b3=std::tr1::shared_ptr (empty) 0x0, b4=...)
at /usr/include/boost/bind/mem_fn_template.hpp:547
#5 0x00007fffef3a2466 in boost::_mfi::cmf4<void, danAPI::StorageClusterFactory, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, danAPI::ConstStorageClusterPtrList const&, danAPI::ConstStorageClusterPtr&, boost::exception_ptr&>::operator()<danAPI::StorageClusterFactory const*> (
this=0x896740, u=@0x896750, a1="/dev/sg4", a2=std::vector of length 1, capacity 1 = {...}, a3=std::tr1::shared_ptr (empty) 0x0, a4=...)
at /usr/include/boost/bind/mem_fn_template.hpp:556
#6 0x00007fffef3a21d4 in boost::_bi::list5<boost::_bi::value<danAPI::StorageClusterFactory const*>, boost::_bi::value<char*>, boost::reference_wrapper<std::vector<std::tr1::shared_ptr<danAPI::StorageCluster const>, std::allocator<std::tr1::shared_ptr<danAPI::StorageCluster const> > > >, boost::reference_wrapper<std::tr1::shared_ptr<danAPI::StorageCluster const> >, boost::reference_wrapper<boost::exception_ptr> >::operator()<boost::_mfi::cmf4<void, danAPI::StorageClusterFactory, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, danAPI::ConstStorageClusterPtrList const&, danAPI::ConstStorageClusterPtr&, boost::exception_ptr&>, boost::_bi::list0> (this=0x896750, f=..., a=...) at /usr/include/boost/bind/bind.hpp:518
#7 0x00007fffef3a1e0d in boost::_bi::bind_t<void, boost::_mfi::cmf4<void, danAPI::StorageClusterFactory, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, danAPI::ConstStorageClusterPtrList const&, danAPI::ConstStorageClusterPtr&, boost::exception_ptr&>, boost::_bi::list5<boost::_bi::value<danAPI::StorageClusterFactory const*>, boost::_bi::value<char*>, boost::reference_wrapper<std::vector<std::tr1::shared_ptr<danAPI::StorageCluster const>, std::allocator<std::tr1::shared_ptr<danAPI::StorageCluster const> > > >, boost::reference_wrapper<std::tr1::shared_ptr<danAPI::StorageCluster const> >, boost::reference_wrapper<boost::exception_ptr> > >::operator() (this=0x896740) at /usr/include/boost/bind/bind_template.hpp:20
#8 0x00007fffef3a19cc in boost::detail::thread_data<boost::_bi::bind_t<void, boost::_mfi::cmf4<void, danAPI::StorageClusterFactory, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, danAPI::ConstStorageClusterPtrList const&, danAPI::ConstStorageClusterPtr&, boost::exception_ptr&>, boost::_bi::list5<boost::_bi::value<danAPI::StorageClusterFactory const*>, boost::_bi::value<char*>, boost::reference_wrapper<std::vector<std::tr1::shared_ptr<danAPI::StorageCluster const>, std::allocator<std::tr1::shared_ptr<danAPI::StorageCluster const> > > >, boost::reference_wrapper<std::tr1::shared_ptr<danAPI::StorageCluster const> >, boost::reference_wrapper<boost::exception_ptr> > > >::run (this=0x896610) at /usr/include/boost/thread/detail/thread.hpp:56
#9 0x00007fffed8c2d97 in thread_proxy () from /usr/lib64/libboost_thread-mt.so.5
#10 0x000000337a007851 in start_thread () from /lib64/libpthread.so.0
#11 0x00000033794e811d in clone () from /lib64/libc.so.6
然后我应该再从setControllerClock()获得2个:
#0 0x000000337c8bccb0 in __cxa_throw () from /usr/lib64/libstdc++.so.6
#1 0x00007ffff143fc4c in swig::SwigPyIteratorClosed_T<__gnu_cxx::__normal_iterator<std::tr1::shared_ptr<danAPI::Controller>*, std::vector<std::tr1::shared_ptr<danAPI::Controller>, std::allocator<std::tr1::shared_ptr<danAPI::Controller> > > >, std::tr1::shared_ptr<danAPI::Controller>, swig::from_oper<std::tr1::shared_ptr<danAPI::Controller> > >::value (this=0x87bf50) at /home/chchr/src/hpsphal/build/python/hpsphalPYTHON_wrap.cxx:4894
#2 0x00007ffff101ddb7 in swig::SwigPyIterator::next (this=0x87bf50) at /home/chchr/src/hpsphal/build/python/hpsphalPYTHON_wrap.cxx:3472
#3 0x00007ffff07a083c in _wrap_SwigPyIterator_next (args=0x7ffff7f69850) at /home/chchr/src/hpsphal/build/python/hpsphalPYTHON_wrap.cxx:14301
#4 0x000000337b8deb24 in PyEval_EvalFrameEx () from /usr/lib64/libpython2.6.so.1.0
#5 0x000000337b8e0797 in PyEval_EvalCodeEx () from /usr/lib64/libpython2.6.so.1.0
#6 0x000000337b86edb0 in ?? () from /usr/lib64/libpython2.6.so.1.0
#7 0x000000337b844303 in PyObject_Call () from /usr/lib64/libpython2.6.so.1.0
#8 0x000000337b85970f in ?? () from /usr/lib64/libpython2.6.so.1.0
#9 0x000000337b844303 in PyObject_Call () from /usr/lib64/libpython2.6.so.1.0
#10 0x000000337b89d5eb in ?? () from /usr/lib64/libpython2.6.so.1.0
#11 0x000000337b8da458 in PyEval_EvalFrameEx () from /usr/lib64/libpython2.6.so.1.0
#12 0x000000337b8e0797 in PyEval_EvalCodeEx () from /usr/lib64/libpython2.6.so.1.0
#13 0x000000337b8e0872 in PyEval_EvalCode () from /usr/lib64/libpython2.6.so.1.0
#14 0x000000337b8fbbbc in ?? () from /usr/lib64/libpython2.6.so.1.0
#15 0x000000337b8fbc90 in PyRun_FileExFlags () from /usr/lib64/libpython2.6.so.1.0
#16 0x000000337b8fd17c in PyRun_SimpleFileExFlags () from /usr/lib64/libpython2.6.so.1.0
#17 0x000000337b909c32 in Py_Main () from /usr/lib64/libpython2.6.so.1.0
#18 0x000000337941ecdd in __libc_start_main () from /lib64/libc.so.6
#19 0x0000000000400649 in _start ()
赶上c ++程序:
Catchpoint 1 (exception thrown), 0x000000337c8bccb0 in __cxa_throw () from /usr/lib64/libstdc++.so.6
(gdb) bt
#0 0x000000337c8bccb0 in __cxa_throw () from /usr/lib64/libstdc++.so.6
#1 0x00007ffff6e9610c in boost::throw_exception<danAPI::Exception> (e=...) at /usr/include/boost/throw_exception.hpp:64
#2 0x00007ffff72a065f in danAPI::Controller_Rcim::setClock (this=0x641430) at /home/chchr/src/hpsphal/storage-lib/src/Controller_Rcim.cpp:2128
#3 0x00000000004072ac in main (argc=1, argv=0x7fffffffe728) at /home/chchr/src/hpsphal/python/foo.cpp:39
答案 0 :(得分:3)
在你的.i文件中,你的%exception
块会在函数周围放置一个try
,然后在每个catch
子句中,它会输出错误然后继续执行,就好像没有例外。这肯定不是你想要的,因为结果是你不会将任何异常传播到Python(你怎么可能?你告诉SWIG生成代码来忽略它们)。使用exception.i,如section 11.1.7 of the SWIG manual中所述。例如,
%include exception.i
%exception {
try {
$action
} catch(const danAPI::Exception& e) {
SWIG_exception(SWIG_ValueError, "Dan API exception");
} catch(const std::exception& e) {
SWIG_exception(SWIG_UnknownError, "Standard exception");
} catch(const boost::exception& e) {
SWIG_exception(SWIG_UnknownError, "Boost exception");
} catch(...) {
SWIG_exception(SWIG_RuntimeError, "Unknown exception");
}
}
我从未查看过生成的代码,但我的猜测是SWIG_exception会导致设置一些标志,SWIG会在执行$ action后检查,如果设置则SWIG使用Python API抛出Python异常。
更新:
如果您从未看到错误消息,并且没有访问catch子句,那么您的C ++库不会抛出异常。问题不在于包装器代码(setControllerClock
),它是您自己的setClock
的C ++库代码,或者您可能没有在引发异常的上下文中调用它。您的问题与生成的代码,SWIG或Python无关。这是你的图书馆。
要证明这一点:在$ action行后面加throw std::runtime_error("test")
。您将在第二个catch子句中结束,e.what()
将是"test"
:
%exception {
try {
$action
throw std::runtime_error("test");
} catch(const danAPI::Exception& e) {
SWIG_exception(SWIG_ValueError, "Dan API exception");
} catch(const std::exception& e) {
SWIG_exception(SWIG_UnknownError, "Standard exception");