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");
}
Thanks for the help
Jörg F.
------------------------------------------------------------------------------
_______________________________________________
Swig-user mailing list
Swig-user@...
https://lists.sourceforge.net/lists/listinfo/swig-user