[C++-sig] [boost.python] Can't import a wrapped template class

2012-10-26 Thread Paul O. Seidon

Hi all,

right now I'm doing my first stepps in wrapping C++ code by ude of Boost.

So, there's a

template class _Variable

with ctor, dtor, an inspector

TYPE value() const

and a mutator

void value( const TYPE& value).

The boost wrapper looks like this:

#include 
#include 
using namespace boost::python;

#include "./src/varbls.h"


#include 
using namespace std;


typedef _Variable  VariableDouble;

BOOST_PYTHON_MODULE(_varbls)
{

class_("VariableDouble")
.def( init<>())
.def( init())
;
}


Nothing special so far. However, what I get upon import is this:

ImportError: 
/usr/lib/python2.7/site-packages/tau4.DDG/tau4/tau4misc/varbls/cpp/boost/_varbls.so: 
undefined symbol: _ZN9_VariableIdEC1Ev


The ctor is decl'ed as

_Variable();

and ist's def'ed like so:

template 
_Variable::_Variable()
: _value( 0)
{
//ctor
}

To me, everything looks good, but obiously there's something wrong. What 
do I miss?


Paul

___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig


Re: [C++-sig] [boost.python] Can't import a wrapped template class

2012-10-26 Thread Stefan Seefeld
On 10/26/2012 07:42 AM, Paul O. Seidon wrote:
> Hi all,
>
> right now I'm doing my first stepps in wrapping C++ code by ude of Boost.

[...]

Where is the definition of your _Variable template instances ? Your
newly compiled Python module can't find them. The likely cause is that
you forgot to link the module to the library containing the definition(s).

Stefan


-- 

  ...ich hab' noch einen Koffer in Berlin...

___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig


Re: [C++-sig] [boost.python] Can't import a wrapped template class

2012-10-26 Thread Paul O. Seidon
Stefan Seefeld wrote:

> On 10/26/2012 07:42 AM, Paul O. Seidon wrote:
>> Hi all,
>>
>> right now I'm doing my first stepps in wrapping C++ code by ude of Boost.
> 
> [...]
> 
> Where is the definition of your _Variable template instances ? Your
> newly compiled Python module can't find them. The likely cause is that
> you forgot to link the module to the library containing the definition(s).
> 
> Stefan
> 
> 

Not sure what you mean:

The ctor is decl'ed in varbls.h as

_Variable();

and it's def'ed in varbls.cpp like so:

template 
_Variable::_Variable()
: _value( 0)
{
 //ctor
}


I did a typedef in the wrapper and wrote

BOOST_PYTHON_MODULE(_varbls)
{

 class_("VariableDouble")
 .def( init<>())
 .def( init())
 ;
}

in the wrapper. 

Any instance of VariableDouble should then be def'ed in the importing Python 
module.

Everything works fine if I do not use templates but plain C++ classes 
instead.


Paul


___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig


Re: [C++-sig] [boost.python] Can't import a wrapped template class

2012-10-26 Thread Stefan Seefeld
On 10/26/2012 01:50 PM, Paul O. Seidon wrote:
> The ctor is decl'ed in varbls.h as
>
> _Variable();
>
> and it's def'ed in varbls.cpp like so:
>
> template 
> _Variable::_Variable()
> : _value( 0)
> {
>  //ctor
> }

That doesn't work. When the compiler compiles varbls.cpp, it doesn't
know what types to instantiate the _Variable template for, so you need
to either explicitly instantiate it for all the types you use in your
module, or keep the definitions in the varbls.h header so the compiler
can implicitly instantiate them when compiling the Python module.

Stefan

-- 

  ...ich hab' noch einen Koffer in Berlin...

___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig


Re: [C++-sig] [boost.python] Can't import a wrapped template class

2012-10-26 Thread Paul O. Seidon
Stefan Seefeld wrote:

> On 10/26/2012 01:50 PM, Paul O. Seidon wrote:
>> The ctor is decl'ed in varbls.h as
>>
>> _Variable();
>>
>> and it's def'ed in varbls.cpp like so:
>>
>> template 
>> _Variable::_Variable()
>> : _value( 0)
>> {
>>  //ctor
>> }
> 
> That doesn't work. When the compiler compiles varbls.cpp, it doesn't
> know what types to instantiate the _Variable template for, so you need
> to either explicitly instantiate it for all the types you use in your
> module, or keep the definitions in the varbls.h header so the compiler
> can implicitly instantiate them when compiling the Python module.
> 
> Stefan
> 

That didn't make any difference. And it would have surprised me, if it did: 
varbls.h contains the declaration, varbls.cpp contains the definition, the 
wrapper is in main.cpp. So if the compiler sees any need to include 
sometihng, it will and the linker will link the definition.

But you certainly are right, the symbol is in the .so-file but the symbol 
isn't resolved by the linker. Hm, but where should I instantiate the class? 
I thought 

BOOST_PYTHON_MODULE(_varbls)
{

 class_("VariableDouble")
 .def( init<>())
 .def( init())
 ;
}

would do that. Should I try

dont_care = _Variable();

in main.cpp? Looks a bit strange, but would force the compiler to generate 
code for sure.

Paul

___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig


Re: [C++-sig] [boost.python] Can't import a wrapped template class

2012-10-26 Thread Paul O. Seidon
Paul O.  Seidon wrote:

> Stefan Seefeld wrote:
> 
>> On 10/26/2012 01:50 PM, Paul O. Seidon wrote:
>>> The ctor is decl'ed in varbls.h as
>>>
>>> _Variable();
>>>
>>> and it's def'ed in varbls.cpp like so:
>>>
>>> template 
>>> _Variable::_Variable()
>>> : _value( 0)
>>> {
>>>  //ctor
>>> }
>> 
>> That doesn't work. When the compiler compiles varbls.cpp, it doesn't
>> know what types to instantiate the _Variable template for, so you need
>> to either explicitly instantiate it for all the types you use in your
>> module, or keep the definitions in the varbls.h header so the compiler
>> can implicitly instantiate them when compiling the Python module.
>> 
>> Stefan
>> 
> 
> That didn't make any difference. And it would have surprised me, if it
> did: varbls.h contains the declaration, varbls.cpp contains the
> definition, the wrapper is in main.cpp. So if the compiler sees any need
> to include sometihng, it will and the linker will link the definition.
> 
> But you certainly are right, the symbol is in the .so-file but the symbol
> isn't resolved by the linker. Hm, but where should I instantiate the
> class? I thought
> 
> BOOST_PYTHON_MODULE(_varbls)
> {
> 
>  class_("VariableDouble")
>  .def( init<>())
>  .def( init())
>  ;
> }
> 
> would do that. Should I try
> 
> dont_care = _Variable();
> 
> in main.cpp? Looks a bit strange, but would force the compiler to generate
> code for sure.
> 
> Paul


That doesn't do it either. I can't help but post the compete code here to be 
sure I'm not misunderstood. The lib consists of varbls.cpp and varbls.h and 
the wrapper main.cpp.

varbls.h


#ifndef VARBLS_H
#define VARBLS_H


template 
class _Variable
{
public:
_Variable();
_Variable( const TYPE& v);
virtual ~_Variable();

TYPEvalue() const;
voidvalue( const double& v);

protected:
private:
TYPE_value;
};


/*
class VariableFloat : public _Variable
{
public:
VariableFloat( const double& v)
: _Variable( v)
{};

virtual ~VariableFloat()
{};
};
*/


class VariableFloat
{
public:
VariableFloat( const double& v=0)
: _value( v)
{};

virtual ~VariableFloat()
{};

double  value() const
{   return _value;
};

voidvalue( const double& v)
{   _value = v;
};

private:
double  _value;
};


#endif // VARBLS_H


varbls.cpp
==

#include "varbls.h"


template 
_Variable::_Variable()
: _value( 0)
{
//ctor
}


template 
_Variable::_Variable( const TYPE& v)
: _value( v)
{
//ctor
}


template 
_Variable::~_Variable()
{
//dtor
}


template  TYPE _Variable::value() const
{
return _value;
}


template  void _Variable::value( const double& v)
{
_value = v;
}


main.cpp


#include 
#include 
using namespace boost::python;

#include "./src/varbls.h"


#include 
using namespace std;


typedef _Variable  VariableDouble;

/*
void(VariableFloat::*value_1)( const double& ) = &VariableFloat::value;
double  (VariableFloat::*value_2)() const = &VariableFloat::value;
*/

BOOST_PYTHON_MODULE(_varbls)
{

class_("VariableDouble")
.def( init<>())
.def( init())
;

/*
class_("VariableFloat")
.def( init<>())
.def( init())
.def( "value", value_1)
.def( "value", value_2)
;
*/
}

VariableDouble  _DONT_CARE = VariableDouble();



Paul


___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig


Re: [C++-sig] [boost.python] Can't import a wrapped template class

2012-10-26 Thread Stefan Seefeld
On 10/26/2012 02:16 PM, Paul O. Seidon wrote:
> Stefan Seefeld wrote:
>
>> On 10/26/2012 01:50 PM, Paul O. Seidon wrote:
>>> The ctor is decl'ed in varbls.h as
>>>
>>> _Variable();
>>>
>>> and it's def'ed in varbls.cpp like so:
>>>
>>> template 
>>> _Variable::_Variable()
>>> : _value( 0)
>>> {
>>>  //ctor
>>> }
>> That doesn't work. When the compiler compiles varbls.cpp, it doesn't
>> know what types to instantiate the _Variable template for, so you need
>> to either explicitly instantiate it for all the types you use in your
>> module, or keep the definitions in the varbls.h header so the compiler
>> can implicitly instantiate them when compiling the Python module.
>>
>> Stefan
>>
> That didn't make any difference. And it would have surprised me, if it did: 
> varbls.h contains the declaration, varbls.cpp contains the definition, the 
> wrapper is in main.cpp. So if the compiler sees any need to include 
> sometihng, it will and the linker will link the definition.

Sorry, let's back up a little. What are you referring to as "the
definition" in the above ?

Where is the "_Variable::_Variable()" constructor defined ? You
didn't show me where it was. You only showed me the (still parametrized)
definition in varbls.cpp. If the compiler sees the parametrized
constructor definition, it doesn't know what types to instantiate it
for, so it does nothing (other than validate the code to some degree).
It's only when it instantiates the template for a particular type that
it generates the missing symbol.
But - according to the small chunks of code you have shown me - it only
attempts that instantiation implicitly in your module's code. But at
that point it doesn't see the constructor definition, so it can't
instantiate that.

Perhaps showing a little more of your code / setup would help.

Stefan

-- 

  ...ich hab' noch einen Koffer in Berlin...

___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig


Re: [C++-sig] [boost.python] Can't import a wrapped template class

2012-10-26 Thread Alex Mohr

On 10/26/2012 11:16 AM, Paul O. Seidon wrote:

would do that. Should I try

dont_care = _Variable();

in main.cpp? Looks a bit strange, but would force the compiler to generate
code for sure.


You either need to inline the ctor in the header or do an explicit 
instantiation of _Variable somewhere.  I suggest you read up on 
"explicit instantiation" and c++ templates in general.  This problem 
isn't related to boost.python.


Alex

___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig


Re: [C++-sig] [boost.python] Can't import a wrapped template class

2012-10-26 Thread Stefan Seefeld
On 10/26/2012 02:24 PM, Paul O. Seidon wrote:
> Paul O.  Seidon wrote:
>
> That doesn't do it either. I can't help but post the compete code here to be 
> sure I'm not misunderstood. The lib consists of varbls.cpp and varbls.h and 
> the wrapper main.cpp.

> varbls.cpp
> ==
>
> #include "varbls.h"
>
>
> template 
> _Variable::_Variable()
> : _value( 0)
> {
> //ctor
> }

[...]

What symbols does your compiled varbls.o file export ? I bet none. And
it can't. That's the problem I'm trying to explain.

Stefan

-- 

  ...ich hab' noch einen Koffer in Berlin...

___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig


Re: [C++-sig] [boost.python] Can't import a wrapped template class

2012-10-26 Thread Paul O. Seidon
Stefan Seefeld wrote:

> On 10/26/2012 02:24 PM, Paul O. Seidon wrote:
>> Paul O.  Seidon wrote:
>>
>> That doesn't do it either. I can't help but post the compete code here to
>> be sure I'm not misunderstood. The lib consists of varbls.cpp and
>> varbls.h and the wrapper main.cpp.
> 
>> varbls.cpp
>> ==
>>
>> #include "varbls.h"
>>
>>
>> template 
>> _Variable::_Variable()
>> : _value( 0)
>> {
>> //ctor
>> }
> 
> [...]
> 
> What symbols does your compiled varbls.o file export ? I bet none. And
> it can't. That's the problem I'm trying to explain.
> 
> Stefan
> 

As Alex said, this seems to be a C++ issue. Hope you'll help me 
nevertheless. There can't be that much that's missing.

How do I do that export?

This whole mess is caused by the use of a template class. You see, there's a 
class VariableFloat. It is not a template class and is not derived from a 
template class. And it works, I can use it from w/i my Python modules. Well, 
it's deactivated for now to prevent "side effects".

Yes, I have to provide a TYPE to the tempate to enable the compiler to 
generate code. Isn't 

typedef _Variable  VariableDouble;

BOOST_PYTHON_MODULE(_varbls)
{

class_("VariableDouble")
.def( init<>())
.def( init())
;
}

doing that?

Paul






___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig


Re: [C++-sig] [boost.python] Can't import a wrapped template class

2012-10-26 Thread Stefan Seefeld
On 10/26/2012 04:15 PM, Paul O. Seidon wrote:

> Yes, I have to provide a TYPE to the tempate to enable the compiler to 
> generate code. Isn't 
>
> typedef _Variable  VariableDouble;
>
> BOOST_PYTHON_MODULE(_varbls)
> {
>
> class_("VariableDouble")
> .def( init<>())
> .def( init())
> ;
> }
>
> doing that?

The compiler can only generate code from templates it can see at the
point where the instantiation happens. Since in the snippet above it
doesn't see the _Variable constructor definition, it can't instantiate
it. And at the point where it can see the constructor, it doesn't know
that it needs to instantiate it for type 'double'.

The entire issue disappears if you move your member function definitions
(including the constructor) from varbls.cpp to varbls.h.

Stefan

-- 

  ...ich hab' noch einen Koffer in Berlin...

___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig


Re: [C++-sig] [boost.python] Can't import a wrapped template class

2012-10-26 Thread Alex Mohr

On 10/26/2012 1:27 PM, Stefan Seefeld wrote:

The entire issue disappears if you move your member function definitions
(including the constructor) from varbls.cpp to varbls.h.


Alternatively, explicitly instantiate in varbls.cpp.

template class _Variable;

Again, you might want to google "explicit template instantiation" or 
similar.


Alex

___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig