La solution est de créer votre classe d'exception comme tout normal ++ classe
class MyCPPException : public std::exception {...}
L'astuce est que tous les boost :: python :: instances class_ tiennent une référence au type de l'objet qui est accessible par leur ptr() fonction. Vous pouvez obtenir ce que vous enregistrez la classe avec boost :: python comme ceci:
class_<MyCPPException> myCPPExceptionClass("MyCPPException"...);
PyObject *myCPPExceptionType=myCPPExceptionClass.ptr();
register_exception_translator<MyCPPException>(&translateFunc);
Enfin, lorsque vous traduisez le C++ exception à une exception Python, vous le faites comme suit:
void translate(MyCPPException const &e)
{
PyErr_SetObject(myCPPExceptionType, boost::python::object(e).ptr());
}
Voici un exemple de travail complet:
#include <boost/python.hpp>
#include <assert.h>
#include <iostream>
class MyCPPException : public std::exception
{
private:
std::string message;
std::string extraData;
public:
MyCPPException(std::string message, std::string extraData)
{
this->message = message;
this->extraData = extraData;
}
const char *what() const throw()
{
return this->message.c_str();
}
~MyCPPException() throw()
{
}
std::string getMessage()
{
return this->message;
}
std::string getExtraData()
{
return this->extraData;
}
};
void my_cpp_function(bool throwException)
{
std::cout << "Called a C++ function." << std::endl;
if (throwException)
{
throw MyCPPException("Throwing an exception as requested.",
"This is the extra data.");
}
}
PyObject *myCPPExceptionType = NULL;
void translateMyCPPException(MyCPPException const &e)
{
assert(myCPPExceptionType != NULL);
boost::python::object pythonExceptionInstance(e);
PyErr_SetObject(myCPPExceptionType, pythonExceptionInstance.ptr());
}
BOOST_PYTHON_MODULE(my_cpp_extension)
{
boost::python::class_<MyCPPException>
myCPPExceptionClass("MyCPPException",
boost::python::init<std::string, std::string>());
myCPPExceptionClass.add_property("message", &MyCPPException::getMessage)
.add_property("extra_data", &MyCPPException::getExtraData);
myCPPExceptionType = myCPPExceptionClass.ptr();
boost::python::register_exception_translator<MyCPPException>
(&translateMyCPPException);
boost::python::def("my_cpp_function", &my_cpp_function);
}
Voici le code Python qui appelle l'extension:
import my_cpp_extension
try:
my_cpp_extension.my_cpp_function(False)
print 'This line should be reached as no exception should be thrown.'
except my_cpp_extension.MyCPPException, e:
print 'Message:', e.message
print 'Extra data:',e.extra_data
try:
my_cpp_extension.my_cpp_function(True)
print ('This line should not be reached as an exception should have been' +
'thrown by now.')
except my_cpp_extension.MyCPPException, e:
print 'Message:', e.message
print 'Extra data:',e.extra_data
** Bonne question & réponse! ** Il a sauvé ma journée! Je vous remercie. –
Excellent! très utile ici aussi! Je voudrais 5x le voter si je pouvais :) –