|
|
Hello
The situation is as follow.
I
have a C++ code that I haven't written and that I barely can modified. I
am supposed to reflect this code in Python with boost. In the code, I have something looking like this:
Class A_Base { A_Base(){}; ~A_Base(){}; Whatever virtual and pure virtual functions; }
Class A_Derived{ A_Derived(Type1 arg1,...){whatever instructions;} ~A_Derived(){}; Whatever functions; }
Class B { B(A_Base& aBase, double& x){}; ~B(){}; Whatever
functions; }
In the C++ main, at some point aDerived A_Derived is set, and then B(aDerived, x). I need to reflect that under python. Until
now, I have been able, with a simple example, to reflect a function f,
which is not a ctor, from a class B using A_Base& as argument type,
but I can't figure out how to deal with it for a constructor. Based on:
http://wiki.python.org/moin/boost.python/ExportingClasses
I am declaring f under both its class B and A_Base as follow:
class_A_Base <A, boost::noncopyable>("A_Base", no_init) //this line can be modified
.def("f", &B::f); class_B <B, boost::noncopyable>("B", init< >()) //this line can be modified
.def("f", &B::f);
But when I try this for a constructor as f, it refuse to compile. Anyone got a clue? Thank you very much in advance for any further help.
_______________________________________________
Cplusplus-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/cplusplus-sig
|
|
On 03/15/2012 09:22 AM, christophe jean-joseph wrote:
> Hello
>
> The situation is as follow.
> I have a C++ code that I haven't written and that I barely can modified.
> I am supposed to reflect this code in Python with boost.
> In the code, I have something looking like this:
>
> Class A_Base {
> A_Base(){};
> ~A_Base(){};
> Whatever virtual and pure virtual functions;
> }
>
> Class A_Derived{
> A_Derived(Type1 arg1,...){whatever instructions;}
> ~A_Derived(){};
> Whatever functions;
> }
>
> Class B {
> B(A_Base& aBase, double& x){};
> ~B(){};
> Whatever functions;
> }
>
> In the C++ main, at some point aDerived A_Derived is set, and then
> B(aDerived, x).
> I need to reflect that under python.
> Until now, I have been able, with a simple example, to reflect a
> function f, which is not a ctor, from a class B using A_Base& as
> argument type, but I can't figure out how to deal with it for a constructor.
> Based on:
>
> http://wiki.python.org/moin/boost.python/ExportingClasses>
> I am declaring f under both its class B and A_Base as follow:
>
> class_A_Base <A, boost::noncopyable>("A_Base", no_init) //this line can
> be modified
> .def("f", &B::f);
> class_B <B, boost::noncopyable>("B", init< >()) //this line can be modified
> .def("f", &B::f);
>
>
> But when I try this for a constructor as f, it refuse to compile.
You don't wrap constructors the same way as functions (I don't think you
can even take their address in C++). Instead, you use:
.def(init<T1,T2,...>())
(where T1,T2,... are the argument types of the constructor), or do the
same thing in the init argument to class_ itself (as I've done below).
I think what you want is something like this (assuming A_Derived does
actually inherit from A_Base, even though it doesn't in your example code):
class_<A_Base,noncopyable>("A_Base", no_init);
class_<A_Derived,bases<A_Base>,noncopyable>("A_Derived", no_init);
class_<B,noncopyable>("B", init<A,double>());
Note that the float you pass in as "x" to B's constructor will not be
modified in Python; that's unavoidable in this case.
If that doesn't work, please post exactly what you're trying to compile;
the example you posted has a few things that obviously won't compile, so
it's hard to know exactly what the problem is.
Good luck!
Jim
_______________________________________________
Cplusplus-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/cplusplus-sig
|
|
Thank you for your answer,
As I said, the solution I am currently using is working fine, I am just using a method explained in the tutorial for a function independant from any class:
http://wiki.python.org/moin/boost.python/ExportingClasses
and I extend it to a function of another class. You recommend to write things that way:
class_< A_i, bp::bases<B> >(...);
but, A_i are not derived from B, and as they are already derived from A_Base_j classes (some from a same base class, not all of them), I already declared their base
classes. Declaring a function B::f(A& a, ...) in A as: .def("f", &B::f) keep C++ declaration (I mean, even if B::f is declared in A, it's declared as a method of B, which is correct). But what your are proposing seems not correct to me, as long as A isn't a derived class from B.
Christophe Jean-Joseph
De : Jim Bosch <[hidden email]> À : christophe jean-joseph <[hidden email]> Envoyé le :
Mercredi 21 mars 2012 4h35 Objet : Re: Re : [C++-sig] Re : [boost] Re : Using an element of a class A in a constructor of a class B (reflection with boost::python) On 03/20/2012 07:07 AM, christophe jean-joseph wrote: > > Thank you for your answer and sorry for the delay: I finally used > another solution. > I used a setParam function instead of the constructor for boost::python. > From the point of view of c++, the only difference is that the former > constructor is now just calling setParam. > This former constructor is ignored by boost::python, and instead > setParam is reflected as a normal function. > This works fine (my Python main produce, with less than 0.01% > difference, the same results as the C++ main). > But I am not satisfied with my solution for the following reason: > if A and B are 2
classes, in order to reflect a function B::f(A& a, > ....), I am writing things as follow as follow: > Class_ <A>(usual declarations here) > .def("f", &B::f) > Class_ <B>(usual declarations here) > .def("f", &B::f) > > Which means, for n classes A_i (i from 1 to n) and a function of a class > B b::f(A_1& a1, A_2& a2,...., A_n& an, ....) I'll have to write: > Class_ <A_1>(usual declarations here) > .def("f", &B::f) > . > . > . > Class_ <A_n>(usual declarations here) > .def("f", &B::f) > Class_ <B>(usual declarations here) > .def("f", &B::f) > > Which is not very clean, even though it's working. > So if there is any other way to do that, I will be glad to hear it. >
I'm a little confused; if the A classes do not inherit from B, why would you want to wrap a
member function of B as a method of A? I don't think they would actually work, unless you've made sure all the A classes are convertible to B by some other mechanism. And if the A classes do inherit from B, if you use: class_< A_i, bp::bases<B> >(...); with no .def("f", ...), you'll still be able to use the "f" method in Python because it will be inherited from B. Jim > ------------------------------------------------------------------------ > *De :* Jim Bosch < [hidden email]> > *À :* christophe jean-joseph < [hidden email]>; Development of > Python/C++ integration < [hidden email]> > *Envoyé le :* Dimanche 18 mars 2012 0h22 > *Objet :* Re: [C++-sig] Re : [boost] Re : Using an element of a class A > in a constructor of a class B (reflection with boost::python) > > On 03/15/2012 09:22 AM, christophe jean-joseph wrote: > > Hello > > > > The situation is as follow. > > I have a C++ code that I haven't written and that I barely can modified. > > I am supposed to reflect this code in Python with boost. > > In the code, I have something looking like this: > > > > Class A_Base { > > A_Base(){}; > > ~A_Base(){}; > > Whatever virtual and pure virtual functions; > > } > > > > Class A_Derived{ > > A_Derived(Type1
arg1,...){whatever instructions;} > > ~A_Derived(){}; > > Whatever functions; > > } > > > > Class B { > > B(A_Base& aBase, double& x){}; > > ~B(){}; > > Whatever functions; > > } > > > > In the C++ main, at some point aDerived A_Derived is set, and then > > B(aDerived, x). > > I need to reflect that under python. > > Until now, I have been able, with a simple example, to reflect a > > function f, which is not a ctor, from a class B using A_Base& as > > argument type, but I can't figure out how to deal with it for a > constructor. > > Based on: > > > > http://wiki.python.org/moin/boost.python/ExportingClasses> > > > I am declaring f under both its class B and A_Base as follow: > > > > class_A_Base <A, boost::noncopyable>("A_Base", no_init) //this line can > > be modified > > .def("f", &B::f); > > class_B <B, boost::noncopyable>("B", init< >()) //this line can be > modified > > .def("f", &B::f); > > > > > > But when I try this for a constructor as f, it refuse to compile. > > You don't wrap constructors the same way as functions (I don't think you > can even take their address in C++). Instead, you use: > > .def(init<T1,T2,...>()) > > (where T1,T2,... are the argument types of the constructor), or do the > same thing in the init
argument to class_ itself (as I've done below). > > I think what you want is something like this (assuming A_Derived does > actually inherit from A_Base, even though it doesn't in your example code): > > class_<A_Base,noncopyable>("A_Base", no_init); > class_<A_Derived,bases<A_Base>,noncopyable>("A_Derived", no_init); > class_<B,noncopyable>("B", init<A,double>()); > > Note that the float you pass in as "x" to B's constructor will not be > modified in Python; that's unavoidable in this case. > > If that doesn't work, please post exactly what you're trying to compile; > the example you posted has a few things that obviously won't compile, so > it's hard to know exactly what the problem is. > > Good luck! > > Jim > > > _______________________________________________
Cplusplus-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/cplusplus-sig
|
|
On 03/21/2012 12:09 PM, christophe jean-joseph wrote:
>
>
> Thank you for your answer,
>
> As I said, the solution I am currently using is working fine, I am just using a method explained in the tutorial for a function independant from any class:
>
> http://wiki.python.org/moin/boost.python/ExportingClasses>
>
> and I extend it to a function of another class.
> You recommend to write things that way:
>
> class_< A_i, bp::bases<B> >(...);
>
>
> but, A_i are not derived from B, and as they are already derived from A_Base_j classes (some from a same base class, not all of them), I already declared their base classes.
> Declaring a function B::f(A& a, ...) in A as:
> .def("f",&B::f)
> keep C++ declaration (I mean, even if B::f is declared in A, it's declared as a method of B, which is correct).
> But what your are proposing seems not correct to me, as long as A isn't a derived class from B.
>
Oh, I understand now. "B::f" is a static member function that takes an
"A" as its first argument. You just want a more elegant way to wrap a
lot of similar classes.
You may not be able to get it a lot cleaner, but you can cut down some
of the boilerplate by writing a templated function to wrap an "A" class.
You can then just call that repeatedly:
template <typename T>
void wrapA(char const * name) {
bp::class_<T>(name, ...)
.def("F", &B::f)
;
}
BOOST_PYTHON_MODULE(whatever) {
wrapA<A_1>("A_1");
wrapA<A_2>("A_2");
...
wrapA<A_n>("A_n");
}
Of course, you'll have to modify it to do more than that, but hopefully
that will get you started.
Jim
_______________________________________________
Cplusplus-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/cplusplus-sig
|
|
Thank you very much for your suggestion.
Jean-Joseph
De : Jim Bosch <[hidden email]> À : christophe jean-joseph <[hidden email]> Cc : "[hidden email]" <[hidden email]> Envoyé le : Mercredi 21
mars 2012 17h32 Objet : Re: Re : Re : [C++-sig] Re : [boost] Re : Using an element of a class A in a constructor of a class B (reflection with boost::python) On 03/21/2012 12:09 PM, christophe jean-joseph wrote: > > > Thank you for your answer, > > As I said, the solution I am currently using is working fine, I am just using a method explained in the tutorial for a function independant from any class: > > http://wiki.python.org/moin/boost.python/ExportingClasses> > > and I extend it to a function of another class. > You recommend to write things that way: > > class_< A_i, bp::bases<B> >(...); > > > but, A_i are not derived from B, and as they are already derived
from A_Base_j classes (some from a same base class, not all of them), I already declared their base classes. > Declaring a function B::f(A& a, ...) in A as: > .def("f",&B::f) > keep C++ declaration (I mean, even if B::f is declared in A, it's declared as a method of B, which is correct). > But what your are proposing seems not correct to me, as long as A isn't a derived class from B. > Oh, I understand now. "B::f" is a static member function that takes an "A" as its first argument. You just want a more elegant way to wrap a lot of similar classes. You may not be able to get it a lot cleaner, but you can cut down some of the boilerplate by writing a templated function to wrap an "A" class. You can then just call that repeatedly: template <typename T> void wrapA(char const * name) { bp::class_<T>(name, ...)
.def("F", &B::f) ; } BOOST_PYTHON_MODULE(whatever) { wrapA<A_1>("A_1"); wrapA<A_2>("A_2"); ... wrapA<A_n>("A_n"); } Of course, you'll have to modify it to do more than that, but hopefully that will get you started. Jim _______________________________________________
Cplusplus-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/cplusplus-sig
|
|