[Swig-user] namespace problem

353 views
Skip to first unread message

Kraus Philipp

unread,
Mar 24, 2012, 5:11:07 AM3/24/12
to swig...@lists.sourceforge.net
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

Philipp Kraus

unread,
Mar 24, 2012, 5:30:38 AM3/24/12
to swig...@lists.sourceforge.net

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

------------------------------------------------------------------------------
This SF email is sponsosred by:
Try Windows Azure free for 90 days Click Here
http://p.sf.net/sfu/sfd2d-msazure
_______________________________________________
Swig-user mailing list
Swig...@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/swig-user

David Froger

unread,
Mar 24, 2012, 8:04:24 AM3/24/12
to swig-user
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

Philipp Kraus

unread,
Mar 24, 2012, 6:12:00 PM3/24/12
to swig...@lists.sourceforge.net
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

Reply all
Reply to author
Forward
0 new messages