From: Kraus P. <phi...@fl...> - 2012-03-24 09:10:41
|
Hello, I try to translate a C++ template class to Python. My Swig interface code shows: %module "mymod" %include "std_vector.i" %include "std_string.i" %{ #include "../../../mainheader.h" %} * %include "../../../template/cpptemplate.hpp" %template(mytest) namespace::subnamespace::class<double>; The cpptemplate.hpp includes the Boost matrix & iostream structurs. If I run Swig with swig -Wall -c++ -python mytest.i I get Error: Unknown namespace 'boost::numeric::ublas' Error: Unknown namespace 'boost::iostreams If I add at * %include "%include "boost/numeric/ublas/matrix.hpp" " and add to the swig command -I<BoostPath> Error: Nothing known about namespace 'boost::numeric::ublas' Warning(302): Identifier 'matrix' redefined (ignored), Warning(302): previous definition of 'matrix'. Warning(302): Identifier 'matrix' redefined (ignored), Warning(302): previous definition of 'matrix'. In my cpptemplate.hpp I use this code lines for namespaces: namespace ublas = boost::numeric::ublas; namespace bio = boost::iostreams; and no using call. How can I solve the problem? Thanks Phil |
From: Philipp K. <phi...@fl...> - 2012-03-24 09:30:23
|
On 2012-03-24 10:11:07 +0100, Kraus Philipp said: > Hello, > > I try to translate a C++ template class to Python. My Swig interface > code shows: > > %module "mymod" > > %include "std_vector.i" > %include "std_string.i" > > > %{ > #include "../../../mainheader.h" > %} > > * > %include "../../../template/cpptemplate.hpp" > %template(mytest) namespace::subnamespace::class<double>; > > > The cpptemplate.hpp includes the Boost matrix & iostream structurs. If > I run Swig with > > swig -Wall -c++ -python mytest.i > > I get > Error: Unknown namespace 'boost::numeric::ublas' > Error: Unknown namespace 'boost::iostreams > > If I add at * %include "%include "boost/numeric/ublas/matrix.hpp" " > and add to the swig command -I<BoostPath> > > Error: Nothing known about namespace 'boost::numeric::ublas' > Warning(302): Identifier 'matrix' redefined (ignored), > Warning(302): previous definition of 'matrix'. > Warning(302): Identifier 'matrix' redefined (ignored), > Warning(302): previous definition of 'matrix'. > > In my cpptemplate.hpp I use this code lines for namespaces: > namespace ublas = boost::numeric::ublas; > namespace bio = boost::iostreams; > and no using call. > > How can I solve the problem? I have add a ifndef around my namespaces: #ifndef SWIG namespace ublas = boost::numeric::ublas; namespace bio = boost::iostreams; #endif but can I do this in my interface file, because I don't want to modify all my code files Thx Phil |
From: David F. <dav...@gm...> - 2012-03-24 12:04:35
|
Hello Philipp, You should #include the headers beetwenn %{ and %} like this: %{ #include "../../../mainheader.h" #include "../../../template/cpptemplate.hpp" #include "%include "boost/numeric/ublas/matrix.hpp" %} Lines beetween %{ and %} are inserted directely in the "header section" of the wrapper file '*_wrap.cxx' generated by Swig, so the code will know about the namespaces. By contrast, if you %include boost/numeric/ublas/matrix.hpp, Swig will try to generate wrapper funtions for function/class defined in matrix.hpp, what you probably don't want. Best, David |
From: David F. <dav...@gm...> - 2012-03-24 15:09:54
Attachments:
swig_ublas_matrix.tar.gz
|
> Why I need this? The boost headers are include in meinheader.h (expecially hpp), > so the include exists during compiling. Ok, I didn't unsderdand that mainheader.h was including boost matrix, sorry! > > Yes, I would change the boost matrix to a jobjectarray for calling on Java. I think I do > this with a type def (out). Is this correct? Yes that right, you need a typemap out. > My method show > > class { > boost::numeric::matrix<double> doit() > } > > and in the JNI call swig should create jobjectarray doit_proxy(). Can I do this with a typedef, the > other way jobjectarray of a argument value to a matrix works fine. I recently write a typemap copying a boost matrix return by reference to a Python numpy array. Its a beginning and will need a lot of improvement, but it works (at least for me). I've attached the tarball, if it can help you (contains everything to be compiled). |
From: Kraus P. <phi...@fl...> - 2012-03-24 19:48:56
|
Hi David, Am 24.03.2012 um 16:09 schrieb David Froger: > I recently write a typemap copying a boost matrix return by reference to a Python numpy array. > Its a beginning and will need a lot of improvement, but it works (at least for me). I've attached > the tarball, if it can help you (contains everything to be compiled). Your example works fine, but I have got some questions: Why do you create this apply rule? %apply (boost::numeric::ublas::matrix<double>&) {(UBlasMatrix&)} You set a typedef in a.hpp to: typedef boost::numeric::ublas::matrix<double> UBlasMatrix; so I think it is redundant I have created a little example to test my source: %module "module" %{ #include "../../java.hpp" #include <boost/numeric/ublas/matrix.hpp> namespace ublas = boost::numeric::ublas; namespace swig = myns::swig; %} %typemap(out) ublas::matrix<double>& { $result = swig::convert::getJObjectArrayFromMatrix(jenv, $1); if (!$result) SWIG_fail; } %inline { ublas::matrix<double> returndata() { ublas::matrix<double> x(3,3); for(std::size_t i=0; i < x.size1(); ++i) for(std::size_t j=0; j < x.size2(); ++j) x(i,j) = (i+1)*(j+1); return x; }; } so I have created a simple function returndata, which returns a ublas matrix. So I want that this matrix is converted to a Java array, the function convert creates a jobjectarray form my ublas matrix (i will change this call with preprocessor flags later for creating Python and PHP arrays). Swig creates at this time a class named SWIGTYPE_p_ublas__matrixTdouble_t. How can I tell swig, that it should create a simple double[][] array and returns them, so that in the resulting Java class a function double[][] returndata() is created? Thanks Phil |
From: Philipp K. <phi...@fl...> - 2012-03-24 22:11:40
|
On 2012-03-24 20:49:20 +0100, Kraus Philipp said: > Am 24.03.2012 um 16:09 schrieb David Froger: > > I recently write a typemap copying a boost matrix return by reference > to a Python numpy array. > Its a beginning and will need a lot of improvement, but it works (at > least for me). I've attached > the tarball, if it can help you (contains everything to be compiled). > > Your example works fine, but I have got some questions: > > Why do you create this apply rule? > %apply (boost::numeric::ublas::matrix<double>&) {(UBlasMatrix&)} > > You set a typedef in a.hpp to: > typedef boost::numeric::ublas::matrix<double> UBlasMatrix; > so I think it is redundant > > I have created a little example to test my source: > > > %module "module" > > %{ > #include "../../java.hpp" > #include <boost/numeric/ublas/matrix.hpp> > namespace ublas = boost::numeric::ublas; > namespace swig = myns::swig; > %} > > > %typemap(out) ublas::matrix<double>& { This line is incorrect, it must be %typemap(argout) ublas::matrix<double> { > $result = swig::convert::getJObjectArrayFromMatrix(jenv, $1); > if (!$result) SWIG_fail; > } > > %inline { > ublas::matrix<double> returndata() { > ublas::matrix<double> x(3,3); > > for(std::size_t i=0; i < x.size1(); ++i) > for(std::size_t j=0; j < x.size2(); ++j) > x(i,j) = (i+1)*(j+1); > > return x; > }; > > } > > so I have created a simple function returndata, which returns a ublas matrix. > So I want that this matrix is converted to a Java array, the function > convert creates > a jobjectarray form my ublas matrix (i will change this call with > preprocessor flags later > for creating Python and PHP arrays). > > Swig creates at this time a class named > SWIGTYPE_p_ublas__matrixTdouble_t. How can I tell > swig, that it should create a simple double[][] array and returns them, > so that in the resulting > Java class a function double[][] returndata() is created? Swig generates this code (I think its the correct code): SWIGEXPORT jlong JNICALL Java_moduleJNI_returndata(JNIEnv *jenv, jclass jcls) { jlong jresult = 0 ; ublas::matrix<double > result; (void)jenv; (void)jcls; result = returndata(); { jresult = swig::convert::getJObjectArrayFromMatrix(jenv, result); if (!jresult) SWIG_fail; } return jresult; } How can I change the jresult type to jobjectarray and within the java class class moduleJNI { public final static native long returndata(); } to public final static native Double[][] returndata(); Thanks Phil |