« Return to Thread: throw exception in c++ and return it to python

Re: throw exception in c++ and return it to python

by "Jörg F. Unger" :: Rate this Message:

Reply to Author | View in Thread

William S Fulton wrote:

> Jörg F. Unger wrote:
>> I'm trying to build a C++ library doing the complex mathematics with a
>> Python interpreter on top of it.
>>
>> In the application it occasionally occurs that exceptions are thrown.
>> I'd like to catch these exceptions in Python, but a really would like to
>> catch not the standard exceptions, but my own exception written in c++
>> and - via swig - wrapped to a Python exception.
>>
>> This is illustrated for a small example.
>>
>> I've got a class Matrix with a setValue method. If the position is out
>> of the range of the allocated memory of the matrix, an exception of the
>> type MyException is thrown.
>>
>> //File Matrix.h
>> #ifndef MATRIX_H
>> #define MATRIX_H
>>
>> #include <vector>
>> #include "MyException.h"
>> class Matrix
>> {
>>
>> public:
>>     Matrix(int numRows_, int numColumns_, std::vector<double> entries_)
>>     {
>>         int numEntries = numRows_ * numColumns_;
>>         if (numEntries!=entries_.size())
>>             throw MyException(std::string("Size of vector does not
>> correspond to number of rows/colums\n"));
>>         entries = entries_;
>>         numRows = numRows_;
>>         numColumns = numColumns_;
>>     }
>>    
>>     void setValue(int row_, int col_, double value)
>>     {
>>         if (row_<0 || col_<0 || row_>=numRows || col_>=numColumns)
>>         {
>>             throw MyException(std::string("Position out of matrix
>> dimension."));
>>         }
>>         else
>>             entries[col_*numRows+row_] = value;
>>     }
>>
>> protected:
>>     int numRows, numColumns;
>>     std::vector<double> entries;
>> };
>>
>>
>> #endif // MATRIX_H
>>
>>
>>
>>
>> //File MyException.h
>> #ifndef MYEXCEPTION_H
>> #define MYEXCEPTION_H
>>
>> #include <string>
>> #include <exception>
>>
>>
>> class MyException : public std::exception
>> {
>>   protected:
>>     std::string message;
>>
>>   public:
>>     explicit MyException(const std::string&  m) : message(m) {}
>>     virtual ~MyException() throw() {}
>>     virtual const char* what() const throw()
>>     {
>>         return message.c_str();
>>     }
>> };
>>
>> #endif  // MYEXCEPTION_H
>>
>>
>> Using swig, I've created the wrapper files using the MyProject.i to
>> create the module MyProject
>>
>> //file MyProject.i
>> %module MyProject
>> %{
>> /* Put headers and other declarations here */
>> #include "Matrix.h"
>> #include "MyException.h"
>> %}
>>
>> // user std::vectors on python level
>> %include "std_vector.i"
>> %include "std_string.i"
>>
>> // Instantiate templates used by example
>> namespace std
>> {
>>    %template(DoubleVector) vector<double>;
>> }
>>
>> %include "MyException.h"
>> %include "exception.i"
>>
>> %exception
>> {
>>   try
>>   {
>>     $action
>>   }
>>   catch (MyException)
>>   {
>>     SWIG_exception_fail(SWIG_ValueError, "MyException");
>>   }
>>
>>   SWIG_CATCH_STDEXCEPT // catch std::exception
>>   catch (...)
>>   {
>>     SWIG_exception_fail(SWIG_UnknownError, "Unknown exception");
>>   }
>> }
>>
>> // provide the public interface
>> %include "Matrix.h"
>>
>>
>> Finally, I've applied this in a Python routine test.py
>>
>> //file test.py
>> import MyProject
>>
>> doubleentries = MyProject.DoubleVector(0)
>> doubleentries.resize(4)
>> doubleentries[0] = 1
>> doubleentries[1] = 2
>> doubleentries[2] = 3
>> doubleentries[3] = 4.5
>>
>> a=MyProject.Matrix(2,2,doubleentries)
>> try:
>>     a.setValue(-1,-1,-1e12)
>>
>> except MyProject.MyException as e:
>>     print e
>>     print "That was MyException"
>> except ValueError as e:
>>     print e
>>     print "That was a Value Error"
>> except :
>>     print "Ohh, some undefined Error occured"
>>
>>
>> What actually happens in the MyProject.i is, that the MyException is
>> catched from the c++ file and swig creates a ValueError-exception, but
>> instead of passing a ValueError-exception (or any other standard
>> exception) to Python, I'd like to pass directly Myexception to Python.
>> Myexception is via SWIG already a data type known in Python, but how can
>> a actually modify the line
>>   catch (MyException)
>>   {
>>     SWIG_exception_fail(SWIG_ValueError, "MyException");
>>   }
>>
>> to something like
>>   catch (MyException)
>>   {
>>     SWIG_exception_fail(SWIG_MyException "MyException");
>>   }
>>
> The example in Examples/python/exceptproxy seems to do what you want.
>
> William

It worked pretty good - thanks for the answer.
Jörg F.



------------------------------------------------------------------------------
_______________________________________________
Swig-user mailing list
Swig-user@...
https://lists.sourceforge.net/lists/listinfo/swig-user

 « Return to Thread: throw exception in c++ and return it to python