pygccxml-development Mailing List for C++ Python language bindings (Page 16)
Brought to you by:
mbaas,
roman_yakovenko
You can subscribe to this list here.
2006 |
Jan
|
Feb
(6) |
Mar
(160) |
Apr
(96) |
May
(152) |
Jun
(72) |
Jul
(99) |
Aug
(189) |
Sep
(161) |
Oct
(110) |
Nov
(9) |
Dec
(3) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2007 |
Jan
(13) |
Feb
(48) |
Mar
(35) |
Apr
(7) |
May
(37) |
Jun
(8) |
Jul
(15) |
Aug
(8) |
Sep
(2) |
Oct
(1) |
Nov
(2) |
Dec
(38) |
2008 |
Jan
(11) |
Feb
(29) |
Mar
(17) |
Apr
(3) |
May
|
Jun
(64) |
Jul
(49) |
Aug
(51) |
Sep
(18) |
Oct
(22) |
Nov
(9) |
Dec
(9) |
2009 |
Jan
(28) |
Feb
(15) |
Mar
(2) |
Apr
(11) |
May
(6) |
Jun
(2) |
Jul
(3) |
Aug
(34) |
Sep
(5) |
Oct
(7) |
Nov
(13) |
Dec
(14) |
2010 |
Jan
(39) |
Feb
(3) |
Mar
(3) |
Apr
(14) |
May
(11) |
Jun
(8) |
Jul
(9) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2011 |
Jan
|
Feb
|
Mar
(7) |
Apr
|
May
|
Jun
(3) |
Jul
(3) |
Aug
(3) |
Sep
|
Oct
|
Nov
|
Dec
|
2015 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
|
Dec
(2) |
2016 |
Jan
(1) |
Feb
(1) |
Mar
|
Apr
(1) |
May
|
Jun
|
Jul
(1) |
Aug
(1) |
Sep
|
Oct
|
Nov
(1) |
Dec
|
2019 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
|
Dec
(1) |
2020 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
|
Dec
(1) |
2021 |
Jan
(1) |
Feb
(1) |
Mar
|
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
(1) |
Nov
|
Dec
|
From: Roman Y. <rom...@gm...> - 2008-07-13 19:00:21
|
On Sun, Jul 13, 2008 at 6:09 PM, Gustavo Carneiro <gjc...@gm...> wrote: > Hi, > > I am trying to wrap methods like this: > > > void SetMac (std::string type, > std::string n0 = "", const AttributeValue &v0 = > EmptyAttributeValue (), > std::string n1 = "", const AttributeValue &v1 = > EmptyAttributeValue (), > std::string n2 = "", const AttributeValue &v2 = > EmptyAttributeValue (), > std::string n3 = "", const AttributeValue &v3 = > EmptyAttributeValue (), > std::string n4 = "", const AttributeValue &v4 = > EmptyAttributeValue (), > std::string n5 = "", const AttributeValue &v5 = > EmptyAttributeValue (), > std::string n6 = "", const AttributeValue &v6 = > EmptyAttributeValue (), > std::string n7 = "", const AttributeValue &v7 = > EmptyAttributeValue ()); > > The problem I am having is that class AttributeValue is abstract and cannot > be instantiated. Normally in pybindgen I handle default values like this: > > PyParameter *pyParam = NULL; > PyArg_ParseTupleAndKeywords("...|O!", ..., &PyParameter_Type, &pyParam); > [...] > CallMyMethod ((pyParam? pyParam->obj : <Param Default Value>)); > > For instance,, if <Param Default> is ns3::EmptyAttributeValue(), I get a > compilation error: > > debug/bindings/python/ns3_module_helper.cc:83: error: cannot allocate an > object of abstract type 'ns3::AttributeValue' > debug/ns3/attribute.h:52: note: since type 'ns3::AttributeValue' has pure > virtual functions > > One solution to this problem would be the following: > > PyParameter *pyParam = NULL; > <Param Default Type> paramDefault = <Param Default Value>; > PyArg_ParseTupleAndKeywords("...|O!", ..., &PyParameter_Type, &pyParam); > [...] > CallMyMethod ((pyParam? pyParam->obj : paramDefault)); > > The above code would compile; I tested. The problem is that pygccxml does > not give me the type of the default parameter value, and of course the type > of the parameter itself is useless in these cases (it is abstract). > > Any suggestion would be welcome. There is a problem with default arguments and gccxml: http://language-binding.net/pygccxml/upgrade_issues.html#free-and-member-function-default-arguments I am not sure what can you do, I will give you few links to other possible solutions: 1. http://www.boost.org/doc/libs/1_35_0/libs/python/doc/v2/overloads.html 2. Second you can ask your users to update default values - pygccxml supports this functionality. May be you will even find some use case, that pygccxml could treat automaticaly: http://language-binding.net/pygccxml/apidocs/pygccxml.parser.patcher-pysrc.html HTH -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Gustavo C. <gjc...@gm...> - 2008-07-13 15:09:24
|
Hi, I am trying to wrap methods like this: void SetMac (std::string type, std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (), std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (), std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (), std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (), std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (), std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (), std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (), std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ()); The problem I am having is that class AttributeValue is abstract and cannot be instantiated. Normally in pybindgen I handle default values like this: PyParameter *pyParam = NULL; PyArg_ParseTupleAndKeywords("...|O!", ..., &PyParameter_Type, &pyParam); [...] CallMyMethod ((pyParam? pyParam->obj : <Param Default Value>)); For instance,, if <Param Default> is ns3::EmptyAttributeValue(), I get a compilation error: debug/bindings/python/ns3_module_helper.cc:83: error: cannot allocate an object of abstract type 'ns3::AttributeValue' debug/ns3/attribute.h:52: note: since type 'ns3::AttributeValue' has pure virtual functions One solution to this problem would be the following: PyParameter *pyParam = NULL; <Param Default Type> paramDefault = <Param Default Value>; PyArg_ParseTupleAndKeywords("...|O!", ..., &PyParameter_Type, &pyParam); [...] CallMyMethod ((pyParam? pyParam->obj : paramDefault)); The above code would compile; I tested. The problem is that pygccxml does not give me the type of the default parameter value, and of course the type of the parameter itself is useless in these cases (it is abstract). Any suggestion would be welcome. -- Gustavo J. A. M. Carneiro INESC Porto, Telecommunications and Multimedia Unit "The universe is always one step beyond logic." -- Frank Herbert |
From: Gordon W. <gor...@gm...> - 2008-07-13 06:09:16
|
> * memory management Oops, forgot to free it in the destructor, thanks for that. I will look into that scoped_ptr thing > * readability I already changed it to use a dictionary on the string formatting which makes it much more readable. On Sun, Jul 13, 2008 at 3:14 PM, Roman Yakovenko <rom...@gm...> wrote: > On Fri, Jul 11, 2008 at 6:51 AM, Gordon Wrigley > <gor...@gm...> wrote: > > I have my char *variables working now, here's the current py++ code I am > > using, any comments would be appreciated > > > > for (className, varName) in stringVars: > > wrapClass = mb.class_(className) > > wrapClass.var(varName).exclude() > > wrapAlias = wrapClass.wrapper_alias > > > > wrapperCode = """ > > char *wrap_%s; > > void set_%s(%s& inst, bp::object obj){ > > char **strPtr = &wrap_%s; > > if(*strPtr != NULL) delete *strPtr; > > bp::extract<std::string> x(obj); > > if (x.check()){ > > std::string str = x(); > > *strPtr = new char[str.length()+1]; > > strcpy_s(*strPtr, str.length()+1, str.c_str()); > > }else{ > > *strPtr = NULL; > > } > > inst.%s = *strPtr; > > } > > static boost::python::object get_%s(%s& inst){ > > std::string str; > > if(inst.%s != NULL){ > > std::string str(inst.%s); > > return bp::object(str); > > }else{ > > return bp::object(); > > } > > } > > """ % (varName, varName, className, varName, varName, varName, > > className, varName, varName) > > wrapClass.add_wrapper_code(wrapperCode) > > > > constructorCode = "wrap_%s = NULL;" % (varName) > > add_constructors_body(wrapClass, constructorCode) > > > > registrationCode = 'add_property("%s", &%s::get_%s, &%s::set_%s)' % > > (varName, wrapAlias, varName, wrapAlias, varName) > > wrapClass.add_registration_code(registrationCode) > > As for me you have few problems in this code: > * memory management > you "set..." function allocates the memory, but you don't release > it. If you have many instances created\destroyed during program > execution you will have serious memory leak > I would use boost::scoped_ptr ( > http://www.boost.org/doc/libs/1_35_0/libs/smart_ptr/scoped_ptr.htm ) > or just plain std::string classes > * readability > wrapperCode contains too many "%s" and it is really difficult to > follow what is going on and modify it letter. I suggest you to use > string.Template class( http://www.python.org/doc/2.5.2/lib/node40.html > ). I am sure, you will be pleased with the result. > > > > -- > Roman Yakovenko > C++ Python language binding > http://www.language-binding.net/ > |
From: Roman Y. <rom...@gm...> - 2008-07-13 05:14:13
|
On Fri, Jul 11, 2008 at 6:51 AM, Gordon Wrigley <gor...@gm...> wrote: > I have my char *variables working now, here's the current py++ code I am > using, any comments would be appreciated > > for (className, varName) in stringVars: > wrapClass = mb.class_(className) > wrapClass.var(varName).exclude() > wrapAlias = wrapClass.wrapper_alias > > wrapperCode = """ > char *wrap_%s; > void set_%s(%s& inst, bp::object obj){ > char **strPtr = &wrap_%s; > if(*strPtr != NULL) delete *strPtr; > bp::extract<std::string> x(obj); > if (x.check()){ > std::string str = x(); > *strPtr = new char[str.length()+1]; > strcpy_s(*strPtr, str.length()+1, str.c_str()); > }else{ > *strPtr = NULL; > } > inst.%s = *strPtr; > } > static boost::python::object get_%s(%s& inst){ > std::string str; > if(inst.%s != NULL){ > std::string str(inst.%s); > return bp::object(str); > }else{ > return bp::object(); > } > } > """ % (varName, varName, className, varName, varName, varName, > className, varName, varName) > wrapClass.add_wrapper_code(wrapperCode) > > constructorCode = "wrap_%s = NULL;" % (varName) > add_constructors_body(wrapClass, constructorCode) > > registrationCode = 'add_property("%s", &%s::get_%s, &%s::set_%s)' % > (varName, wrapAlias, varName, wrapAlias, varName) > wrapClass.add_registration_code(registrationCode) As for me you have few problems in this code: * memory management you "set..." function allocates the memory, but you don't release it. If you have many instances created\destroyed during program execution you will have serious memory leak I would use boost::scoped_ptr ( http://www.boost.org/doc/libs/1_35_0/libs/smart_ptr/scoped_ptr.htm ) or just plain std::string classes * readability wrapperCode contains too many "%s" and it is really difficult to follow what is going on and modify it letter. I suggest you to use string.Template class( http://www.python.org/doc/2.5.2/lib/node40.html ). I am sure, you will be pleased with the result. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Roman Y. <rom...@gm...> - 2008-07-13 04:59:18
|
On Fri, Jul 11, 2008 at 4:40 AM, Gordon Wrigley <gor...@gm...> wrote: > it would be nice to have an add version of set_constructors_body that > appends stuff I can add this. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Gordon W. <gor...@gm...> - 2008-07-11 03:51:09
|
I have my char *variables working now, here's the current py++ code I am using, any comments would be appreciated for (className, varName) in stringVars: wrapClass = mb.class_(className) wrapClass.var(varName).exclude() wrapAlias = wrapClass.wrapper_alias wrapperCode = """ char *wrap_%s; void set_%s(%s& inst, bp::object obj){ char **strPtr = &wrap_%s; if(*strPtr != NULL) delete *strPtr; bp::extract<std::string> x(obj); if (x.check()){ std::string str = x(); *strPtr = new char[str.length()+1]; strcpy_s(*strPtr, str.length()+1, str.c_str()); }else{ *strPtr = NULL; } inst.%s = *strPtr; } static boost::python::object get_%s(%s& inst){ std::string str; if(inst.%s != NULL){ std::string str(inst.%s); return bp::object(str); }else{ return bp::object(); } } """ % (varName, varName, className, varName, varName, varName, className, varName, varName) wrapClass.add_wrapper_code(wrapperCode) constructorCode = "wrap_%s = NULL;" % (varName) add_constructors_body(wrapClass, constructorCode) registrationCode = 'add_property("%s", &%s::get_%s, &%s::set_%s)' % (varName, wrapAlias, varName, wrapAlias, varName) wrapClass.add_registration_code(registrationCode) |
From: Gordon W. <gor...@gm...> - 2008-07-11 01:39:59
|
it would be nice to have an add version of set_constructors_body that appends stuff |
From: Gordon W. <gor...@gm...> - 2008-07-10 06:23:02
|
On the documentation front, the main thing that was confusing me is that menu in the top left, once I realised that it was the main navigation tool getting around the docs got a lot easier. Also the insight that all those vars, mem_funs etc functions in module_builder_t return further module_builder_t's helped a lot. I'm getting the documentation now and it's helping a lot. With regard to the example... I already mentioned that getName is going. I put the getters and setters in for the fred/planet example and the class properties section of this page http://www.boost.org/doc/libs/1_35_0/libs/python/doc/tutorial/doc/html/python/exposing.htmlthat you sent me earlier (thanks for that) helped me figure out how to tie them in in the way I want, testing that at the moment and it seems to be working. The loadFile example was already working (and I had already tested it in a different context but hadn't realised) Will start into the image and data examples after the current round of testing. All in all today is going very well. On Thu, Jul 10, 2008 at 4:07 PM, Roman Yakovenko <rom...@gm...> wrote: > On Thu, Jul 10, 2008 at 3:06 AM, Gordon Wrigley > <gor...@gm...> wrote: > > on > http://language-binding.net/pyplusplus/documentation/how_to/how_to.html I > > believe the following code: > > > > registration_code = 'def( "get_size", &%s::get_size )' % > > window.wrapper_alias > > > > mb = module_builder_t( ... ) > > window = mb.class_( "window_t" ) > > window.member_function( "get_size" ).exclude() > > window.add_wrapper_code( wrapper_code ) > > window.registration_code( registration_code ) > > > > should instead read > > > > mb = module_builder_t( ... ) > > window = mb.class_( "window_t" ) > > window.member_function( "get_size" ).exclude() > > window.add_wrapper_code( wrapper_code ) > > registration_code = 'def( "get_size", &%s::get_size )' % > > window.wrapper_alias > > window.add_registration_code( registration_code ) > > > > and I now have the getName example working > > This your first contribution to the project :-) > > Thanks. I fixed it. > > > -- > Roman Yakovenko > C++ Python language binding > http://www.language-binding.net/ > |
From: Roman Y. <rom...@gm...> - 2008-07-10 06:09:48
|
On Thu, Jul 10, 2008 at 8:07 AM, Gordon Wrigley <gor...@gm...> wrote: > With regard to > http://www.language-binding.net/pyplusplus/documentation/apidocs/pyplusplus.module_builder.builder.module_builder_t-class.html > Is there a document that explains exactly what the different methods (ie > vars, calldefs, mem_funs, decls, etc, etc) correspond to, some of them, like > vars for example are reasonably obvious, but others like call_defs are not > as obvious. may be this: http://www.language-binding.net/pygccxml/declarations_uml.png "calldef" is the pygccxml( Py++ ) way to name functions. It is the base class for: constructors, destructors, operators, free and member functions. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Roman Y. <rom...@gm...> - 2008-07-10 06:07:11
|
On Thu, Jul 10, 2008 at 3:06 AM, Gordon Wrigley <gor...@gm...> wrote: > on http://language-binding.net/pyplusplus/documentation/how_to/how_to.html I > believe the following code: > > registration_code = 'def( "get_size", &%s::get_size )' % > window.wrapper_alias > > mb = module_builder_t( ... ) > window = mb.class_( "window_t" ) > window.member_function( "get_size" ).exclude() > window.add_wrapper_code( wrapper_code ) > window.registration_code( registration_code ) > > should instead read > > mb = module_builder_t( ... ) > window = mb.class_( "window_t" ) > window.member_function( "get_size" ).exclude() > window.add_wrapper_code( wrapper_code ) > registration_code = 'def( "get_size", &%s::get_size )' % > window.wrapper_alias > window.add_registration_code( registration_code ) > > and I now have the getName example working This your first contribution to the project :-) Thanks. I fixed it. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Gordon W. <gor...@gm...> - 2008-07-10 05:07:28
|
With regard to http://www.language-binding.net/pyplusplus/documentation/apidocs/pyplusplus.module_builder.builder.module_builder_t-class.html Is there a document that explains exactly what the different methods (ie vars, calldefs, mem_funs, decls, etc, etc) correspond to, some of them, like vars for example are reasonably obvious, but others like call_defs are not as obvious. On Thu, Jul 10, 2008 at 10:06 AM, Gordon Wrigley <gor...@gm...> wrote: > on http://language-binding.net/pyplusplus/documentation/how_to/how_to.htmlI believe the following code: > > registration_code = 'def( "get_size", &%s::get_size )' % > window.wrapper_alias > > mb = module_builder_t( ... ) > window = mb.class_( "window_t" ) > window.member_function( "get_size" ).exclude() > window.add_wrapper_code( wrapper_code ) > window.registration_code( registration_code ) > > should instead read > > mb = module_builder_t( ... ) > window = mb.class_( "window_t" ) > window.member_function( "get_size" ).exclude() > window.add_wrapper_code( wrapper_code ) > registration_code = 'def( "get_size", &%s::get_size )' % > window.wrapper_alias > window.add_registration_code( registration_code ) > > and I now have the getName example working > > > > On Wed, Jul 9, 2008 at 9:49 PM, Gordon Wrigley <gor...@gm...> > wrote: > >> > May we switch to the mailing list? There a lot of advantages to use it. >> >> Sure I just dropped off the mailing list so there wouldn't be so much >> noise for everyone else. >> >> > The important question is: how "pythonic" your interface should be? >> >> It needs to be quite pythonic, the eventual users aren't programmers by >> trade and only have exposure to python, no C or C++ abilities, I really >> can't count on them being careful at all. >> I'd also like keep it all within the library, where there have to be >> wrappers I'd rather they were not visible to the end users. >> >> > void getName(char *buff, int len){ >> > strncpy(buff, "bob", len); >> > } >> > Hmm. In this case we can create new function transformation >> > Another solution is to generate wrapper for such functions and to expose >> it. >> >> The best wrapper option I can think of for this is: >> static boost::python::object getName(const Bob& bob, int len){ >> char buf[len]; >> bob.getName(buf, len); >> std::string hw2(buf); >> return bp::object( hw2 ); >> } >> And then I guess I do this stuff >> http://language-binding.net/pyplusplus/documentation/how_to/how_to.htmlin py++ which all seems straight forward, unfortunately I can't test it >> until I get to work tomorrow. >> I'm not sure if this would be useful enough for other people to justify >> turning it into a transform. >> >> >> The planet example seems to work fine (you suggested in another mail >> that it >> >> might). >> > Good >> >> Sorry, my mistake I haven't actually tested the planet example, what I >> have tested is reading a char array, and that works. >> However when the the char array contains a nul terminated string the >> interface is somewhat ugly so I'm considering wrapping those, but that's a >> problem for later. >> I will check the planet example in the morning but I suspect at this stage >> it's just not being exported at all, I know for sure that char* variables >> aren't showing up at all in the generated cpp file. >> >> > char *fred; >> > Consider my advice about ctypes. >> > I can patch Py++ today, so instead of exposing the variable it will >> > expose the variable address: >> >> Thank you but I think I'd rather avoid that. >> I think can see now how I could produce and tie in get_fred and set_fred >> functions and how not to leak memory while doing it, I will give that a go >> tomorrow and we'll see how it works out. >> What I would like to do that I can't currently see a way of achieving is >> to wrap those get and set functions together into something that looks like >> a variable so on the python side instead of going >> bob.set_fred("hello") >> print bob.get_fred() >> I can use it like this instead >> bob.fred="hello" >> print bob.fred >> This is a nice to have as it means I don't have to deviate as much from >> the C++ api and once this is all going I'm going to have to document >> everywhere where I deviate from that api. >> >> >> I haven't tested the loadFile example yet and I consider it low >> priority. >> > I guess "modify_type" function transformation could be used. It is a >> little bit ugly but it will work >> >> It may already be working, like I said I haven't tried it yet, however it >> is showing up in the generated cpp file so maybe it's all good. >> >> >> On Wed, Jul 9, 2008 at 7:01 PM, Roman Yakovenko < >> rom...@gm...> wrote: >> >>> On Wed, Jul 9, 2008 at 10:43 AM, Gordon Wrigley >>> <gor...@gm...> wrote: >>> > Ok, the disclaimers again, I'm not an expert at either C++ or Python >>> but I >>> > can get by in both, I don't generally use windows and I haven't done >>> any >>> > development for or on windows in years and I've never used boost or >>> msvc >>> > before. >>> >>> May we switch to the mailing list? There a lot of advantages to use it. >>> >>> > My work has recently acquired a moderately large and expensive piece of >>> test >>> > equipment. This device has a bunch of windows dlls with C++ headers for >>> > developing automation tools. These headers total several thousand >>> lines. >>> > I've been given the job of making it work from Python which is our >>> > automation language of choice. I got the job because I have an >>> established >>> > history of being able to slove problems. >>> > >>> > Currently I have a py++ script that gets most of the stuff exported but >>> it's >>> > hard to say how much is exported correctly. Currently the script >>> produces >>> > ~170 lines of warnings and I understand them all (this is a big step up >>> from >>> > yesterday). I've gotten the bjam stuff sorted and I can compile link >>> all the >>> > various dlls (it also uses the matlab common runtime). Then from the >>> python >>> > console I can import the lib (that was a big step all the dll's have to >>> be >>> > in line for that to work) run the initilization stuff and connect to >>> the >>> > device, or at least I appear to connect I haven't been able to do >>> anything >>> > useful with it yet. >>> >>> I understand your warnings and lack of confidence. I tried to build Py++ >>> in a >>> such way, that if it exports thing they work, otherwise there is a >>> warning or >>> the declaration is not exported. >>> >>> > Alot of the stuff in the headers is very basic C like, so char*'s >>> instead of >>> > strings, arrays of pointers, pointer passing etc and very little in the >>> way >>> > of OO design or C++ style memory management, actually there's very >>> little >>> > dynamic memory stuff at all. >>> > >>> > I realise that to get a lot of it going I will need to do make custom >>> > handlers and that's ok, once I have the first couple of those going I >>> should >>> > be able to figure the rest out quite quickly. >>> > >>> > As an example of some of the stuff I need, in the following C++ code >>> (which >>> > should compile and run with a couple of warnings) I need to be able to >>> do >>> > all the stuff in the main function from python. >>> >>> The important question is: how "pythonic" your interface should be? >>> I will explain: in almost no time, you can generate code that returns the >>> address of the variable, than you can use ctypes built-in module to work >>> with >>> that variable. Take a look on >>> http://python.net/crew/theller/ctypes/reference.html#data-types >>> "from_address" function. >>> >>> Of course your users will have to be very very careful. >>> >>> You can improve and to create small wrappers around classes in Python >>> that checks preconditions. >>> >>> Another approach is to expose "Pythonic" API, but it has its price and >>> this is not cheep. I suggest you to go >>> with the first one. >>> >>> > #include <iostream> >>> > >>> > class Bob{ >>> > public: >>> > char *fred; >>> > char *planet; >>> > double image[10]; >>> > double *data[2]; >>> > >>> > Bob(){ >>> > planet="Naboo"; >>> > >>> > for(int i=0; i<10; i++) image[i]=i; >>> > >>> > data[0] = new double[5]; >>> > data[1] = new double[5]; >>> > for(int i=0; i<5; i++){ >>> > data[0][i] = 5-i; >>> > data[1][i] = i+5; >>> > } >>> > } >>> > >>> > void getName(char *buff, int len){ >>> > strncpy(buff, "bob", len); >>> > } >>> > >>> > int loadFile(char *name){ >>> > // do stuff >>> > return 0; >>> > } >>> > }; >>> > >>> > int main(int argc, char **argv){ >>> > Bob *bob = new Bob(); >>> > std::cout << "bob->planet = " << bob->planet << std::endl; >>> > >>> > bob->fred = "ABC"; >>> > std::cout << "bob->fred = " << bob->fred << std::endl; >>> > >>> > char buff[10]; >>> > bob->getName(buff, 10); >>> > std::cout << "buff = " << buff << std::endl; >>> > >>> > std::cout << "bob->image[7] = " << bob->image[7] << std::endl; >>> > >>> > std::cout << "bob->data[1][2] = " << bob->data[1][2] << std::endl; >>> > >>> > std::cout << "bob->loadFile = " << bob->loadFile("data.dat") << >>> > std::endl; >>> > } >>> > >>> > Getting the getName example above going is probably my most pressing >>> need as >>> > I need that to get version and status info off the device in order to >>> verify >>> > that I do actually have a valid connection. >>> >>> Hmm. In this case we can create new function transformation >>> ( >>> http://language-binding.net/pyplusplus/documentation/functions/transformation/transformation.html >>> ) >>> >>> It should not be too difficult. >>> >>> Another solution is to generate wrapper for such functions and to expose >>> it. >>> >>> > The planet example seems to work fine (you suggested in another mail >>> that it >>> > might). >>> >>> Good >>> >>> > Once I get the fred example going I can probably figure out the the >>> image >>> > and data ones. >>> >>> Consider my advice about ctypes. >>> >>> I can patch Py++ today, so instead of exposing the variable it will >>> expose the variable address: >>> >>> mb = module_builder_t( ... ) >>> mb.var( 'fred' ).expose_address = True >>> >>> Better name for property is welcome >>> >>> > I haven't tested the loadFile example yet and I consider it low >>> priority. >>> >>> I guess "modify_type" function transformation could be used. It is a >>> little bit ugly >>> but it will work >>> >>> > Also I very much appreciate the help you have been giving me, thank >>> you. >>> >>> My pleasure. >>> >>> -- >>> Roman Yakovenko >>> C++ Python language binding >>> http://www.language-binding.net/ >>> >> >> > |
From: Gordon W. <gor...@gm...> - 2008-07-10 00:06:36
|
on http://language-binding.net/pyplusplus/documentation/how_to/how_to.html I believe the following code: registration_code = 'def( "get_size", &%s::get_size )' % window.wrapper_alias mb = module_builder_t( ... ) window = mb.class_( "window_t" ) window.member_function( "get_size" ).exclude() window.add_wrapper_code( wrapper_code ) window.registration_code( registration_code ) should instead read mb = module_builder_t( ... ) window = mb.class_( "window_t" ) window.member_function( "get_size" ).exclude() window.add_wrapper_code( wrapper_code ) registration_code = 'def( "get_size", &%s::get_size )' % window.wrapper_alias window.add_registration_code( registration_code ) and I now have the getName example working On Wed, Jul 9, 2008 at 9:49 PM, Gordon Wrigley <gor...@gm...> wrote: > > May we switch to the mailing list? There a lot of advantages to use it. > > Sure I just dropped off the mailing list so there wouldn't be so much noise > for everyone else. > > > The important question is: how "pythonic" your interface should be? > > It needs to be quite pythonic, the eventual users aren't programmers by > trade and only have exposure to python, no C or C++ abilities, I really > can't count on them being careful at all. > I'd also like keep it all within the library, where there have to be > wrappers I'd rather they were not visible to the end users. > > > void getName(char *buff, int len){ > > strncpy(buff, "bob", len); > > } > > Hmm. In this case we can create new function transformation > > Another solution is to generate wrapper for such functions and to expose > it. > > The best wrapper option I can think of for this is: > static boost::python::object getName(const Bob& bob, int len){ > char buf[len]; > bob.getName(buf, len); > std::string hw2(buf); > return bp::object( hw2 ); > } > And then I guess I do this stuff > http://language-binding.net/pyplusplus/documentation/how_to/how_to.html in > py++ which all seems straight forward, unfortunately I can't test it until I > get to work tomorrow. > I'm not sure if this would be useful enough for other people to justify > turning it into a transform. > > >> The planet example seems to work fine (you suggested in another mail > that it > >> might). > > Good > > Sorry, my mistake I haven't actually tested the planet example, what I have > tested is reading a char array, and that works. > However when the the char array contains a nul terminated string the > interface is somewhat ugly so I'm considering wrapping those, but that's a > problem for later. > I will check the planet example in the morning but I suspect at this stage > it's just not being exported at all, I know for sure that char* variables > aren't showing up at all in the generated cpp file. > > > char *fred; > > Consider my advice about ctypes. > > I can patch Py++ today, so instead of exposing the variable it will > > expose the variable address: > > Thank you but I think I'd rather avoid that. > I think can see now how I could produce and tie in get_fred and set_fred > functions and how not to leak memory while doing it, I will give that a go > tomorrow and we'll see how it works out. > What I would like to do that I can't currently see a way of achieving is to > wrap those get and set functions together into something that looks like a > variable so on the python side instead of going > bob.set_fred("hello") > print bob.get_fred() > I can use it like this instead > bob.fred="hello" > print bob.fred > This is a nice to have as it means I don't have to deviate as much from the > C++ api and once this is all going I'm going to have to document everywhere > where I deviate from that api. > > >> I haven't tested the loadFile example yet and I consider it low > priority. > > I guess "modify_type" function transformation could be used. It is a > little bit ugly but it will work > > It may already be working, like I said I haven't tried it yet, however it > is showing up in the generated cpp file so maybe it's all good. > > > On Wed, Jul 9, 2008 at 7:01 PM, Roman Yakovenko <rom...@gm...> > wrote: > >> On Wed, Jul 9, 2008 at 10:43 AM, Gordon Wrigley >> <gor...@gm...> wrote: >> > Ok, the disclaimers again, I'm not an expert at either C++ or Python but >> I >> > can get by in both, I don't generally use windows and I haven't done any >> > development for or on windows in years and I've never used boost or msvc >> > before. >> >> May we switch to the mailing list? There a lot of advantages to use it. >> >> > My work has recently acquired a moderately large and expensive piece of >> test >> > equipment. This device has a bunch of windows dlls with C++ headers for >> > developing automation tools. These headers total several thousand lines. >> > I've been given the job of making it work from Python which is our >> > automation language of choice. I got the job because I have an >> established >> > history of being able to slove problems. >> > >> > Currently I have a py++ script that gets most of the stuff exported but >> it's >> > hard to say how much is exported correctly. Currently the script >> produces >> > ~170 lines of warnings and I understand them all (this is a big step up >> from >> > yesterday). I've gotten the bjam stuff sorted and I can compile link all >> the >> > various dlls (it also uses the matlab common runtime). Then from the >> python >> > console I can import the lib (that was a big step all the dll's have to >> be >> > in line for that to work) run the initilization stuff and connect to the >> > device, or at least I appear to connect I haven't been able to do >> anything >> > useful with it yet. >> >> I understand your warnings and lack of confidence. I tried to build Py++ >> in a >> such way, that if it exports thing they work, otherwise there is a warning >> or >> the declaration is not exported. >> >> > Alot of the stuff in the headers is very basic C like, so char*'s >> instead of >> > strings, arrays of pointers, pointer passing etc and very little in the >> way >> > of OO design or C++ style memory management, actually there's very >> little >> > dynamic memory stuff at all. >> > >> > I realise that to get a lot of it going I will need to do make custom >> > handlers and that's ok, once I have the first couple of those going I >> should >> > be able to figure the rest out quite quickly. >> > >> > As an example of some of the stuff I need, in the following C++ code >> (which >> > should compile and run with a couple of warnings) I need to be able to >> do >> > all the stuff in the main function from python. >> >> The important question is: how "pythonic" your interface should be? >> I will explain: in almost no time, you can generate code that returns the >> address of the variable, than you can use ctypes built-in module to work >> with >> that variable. Take a look on >> http://python.net/crew/theller/ctypes/reference.html#data-types >> "from_address" function. >> >> Of course your users will have to be very very careful. >> >> You can improve and to create small wrappers around classes in Python >> that checks preconditions. >> >> Another approach is to expose "Pythonic" API, but it has its price and >> this is not cheep. I suggest you to go >> with the first one. >> >> > #include <iostream> >> > >> > class Bob{ >> > public: >> > char *fred; >> > char *planet; >> > double image[10]; >> > double *data[2]; >> > >> > Bob(){ >> > planet="Naboo"; >> > >> > for(int i=0; i<10; i++) image[i]=i; >> > >> > data[0] = new double[5]; >> > data[1] = new double[5]; >> > for(int i=0; i<5; i++){ >> > data[0][i] = 5-i; >> > data[1][i] = i+5; >> > } >> > } >> > >> > void getName(char *buff, int len){ >> > strncpy(buff, "bob", len); >> > } >> > >> > int loadFile(char *name){ >> > // do stuff >> > return 0; >> > } >> > }; >> > >> > int main(int argc, char **argv){ >> > Bob *bob = new Bob(); >> > std::cout << "bob->planet = " << bob->planet << std::endl; >> > >> > bob->fred = "ABC"; >> > std::cout << "bob->fred = " << bob->fred << std::endl; >> > >> > char buff[10]; >> > bob->getName(buff, 10); >> > std::cout << "buff = " << buff << std::endl; >> > >> > std::cout << "bob->image[7] = " << bob->image[7] << std::endl; >> > >> > std::cout << "bob->data[1][2] = " << bob->data[1][2] << std::endl; >> > >> > std::cout << "bob->loadFile = " << bob->loadFile("data.dat") << >> > std::endl; >> > } >> > >> > Getting the getName example above going is probably my most pressing >> need as >> > I need that to get version and status info off the device in order to >> verify >> > that I do actually have a valid connection. >> >> Hmm. In this case we can create new function transformation >> ( >> http://language-binding.net/pyplusplus/documentation/functions/transformation/transformation.html >> ) >> >> It should not be too difficult. >> >> Another solution is to generate wrapper for such functions and to expose >> it. >> >> > The planet example seems to work fine (you suggested in another mail >> that it >> > might). >> >> Good >> >> > Once I get the fred example going I can probably figure out the the >> image >> > and data ones. >> >> Consider my advice about ctypes. >> >> I can patch Py++ today, so instead of exposing the variable it will >> expose the variable address: >> >> mb = module_builder_t( ... ) >> mb.var( 'fred' ).expose_address = True >> >> Better name for property is welcome >> >> > I haven't tested the loadFile example yet and I consider it low >> priority. >> >> I guess "modify_type" function transformation could be used. It is a >> little bit ugly >> but it will work >> >> > Also I very much appreciate the help you have been giving me, thank you. >> >> My pleasure. >> >> -- >> Roman Yakovenko >> C++ Python language binding >> http://www.language-binding.net/ >> > > |
From: Gordon W. <gor...@gm...> - 2008-07-09 11:48:57
|
> May we switch to the mailing list? There a lot of advantages to use it. Sure I just dropped off the mailing list so there wouldn't be so much noise for everyone else. > The important question is: how "pythonic" your interface should be? It needs to be quite pythonic, the eventual users aren't programmers by trade and only have exposure to python, no C or C++ abilities, I really can't count on them being careful at all. I'd also like keep it all within the library, where there have to be wrappers I'd rather they were not visible to the end users. > void getName(char *buff, int len){ > strncpy(buff, "bob", len); > } > Hmm. In this case we can create new function transformation > Another solution is to generate wrapper for such functions and to expose it. The best wrapper option I can think of for this is: static boost::python::object getName(const Bob& bob, int len){ char buf[len]; bob.getName(buf, len); std::string hw2(buf); return bp::object( hw2 ); } And then I guess I do this stuff http://language-binding.net/pyplusplus/documentation/how_to/how_to.html in py++ which all seems straight forward, unfortunately I can't test it until I get to work tomorrow. I'm not sure if this would be useful enough for other people to justify turning it into a transform. >> The planet example seems to work fine (you suggested in another mail that it >> might). > Good Sorry, my mistake I haven't actually tested the planet example, what I have tested is reading a char array, and that works. However when the the char array contains a nul terminated string the interface is somewhat ugly so I'm considering wrapping those, but that's a problem for later. I will check the planet example in the morning but I suspect at this stage it's just not being exported at all, I know for sure that char* variables aren't showing up at all in the generated cpp file. > char *fred; > Consider my advice about ctypes. > I can patch Py++ today, so instead of exposing the variable it will > expose the variable address: Thank you but I think I'd rather avoid that. I think can see now how I could produce and tie in get_fred and set_fred functions and how not to leak memory while doing it, I will give that a go tomorrow and we'll see how it works out. What I would like to do that I can't currently see a way of achieving is to wrap those get and set functions together into something that looks like a variable so on the python side instead of going bob.set_fred("hello") print bob.get_fred() I can use it like this instead bob.fred="hello" print bob.fred This is a nice to have as it means I don't have to deviate as much from the C++ api and once this is all going I'm going to have to document everywhere where I deviate from that api. >> I haven't tested the loadFile example yet and I consider it low priority. > I guess "modify_type" function transformation could be used. It is a little bit ugly but it will work It may already be working, like I said I haven't tried it yet, however it is showing up in the generated cpp file so maybe it's all good. On Wed, Jul 9, 2008 at 7:01 PM, Roman Yakovenko <rom...@gm...> wrote: > On Wed, Jul 9, 2008 at 10:43 AM, Gordon Wrigley > <gor...@gm...> wrote: > > Ok, the disclaimers again, I'm not an expert at either C++ or Python but > I > > can get by in both, I don't generally use windows and I haven't done any > > development for or on windows in years and I've never used boost or msvc > > before. > > May we switch to the mailing list? There a lot of advantages to use it. > > > My work has recently acquired a moderately large and expensive piece of > test > > equipment. This device has a bunch of windows dlls with C++ headers for > > developing automation tools. These headers total several thousand lines. > > I've been given the job of making it work from Python which is our > > automation language of choice. I got the job because I have an > established > > history of being able to slove problems. > > > > Currently I have a py++ script that gets most of the stuff exported but > it's > > hard to say how much is exported correctly. Currently the script produces > > ~170 lines of warnings and I understand them all (this is a big step up > from > > yesterday). I've gotten the bjam stuff sorted and I can compile link all > the > > various dlls (it also uses the matlab common runtime). Then from the > python > > console I can import the lib (that was a big step all the dll's have to > be > > in line for that to work) run the initilization stuff and connect to the > > device, or at least I appear to connect I haven't been able to do > anything > > useful with it yet. > > I understand your warnings and lack of confidence. I tried to build Py++ in > a > such way, that if it exports thing they work, otherwise there is a warning > or > the declaration is not exported. > > > Alot of the stuff in the headers is very basic C like, so char*'s instead > of > > strings, arrays of pointers, pointer passing etc and very little in the > way > > of OO design or C++ style memory management, actually there's very little > > dynamic memory stuff at all. > > > > I realise that to get a lot of it going I will need to do make custom > > handlers and that's ok, once I have the first couple of those going I > should > > be able to figure the rest out quite quickly. > > > > As an example of some of the stuff I need, in the following C++ code > (which > > should compile and run with a couple of warnings) I need to be able to do > > all the stuff in the main function from python. > > The important question is: how "pythonic" your interface should be? > I will explain: in almost no time, you can generate code that returns the > address of the variable, than you can use ctypes built-in module to work > with > that variable. Take a look on > http://python.net/crew/theller/ctypes/reference.html#data-types > "from_address" function. > > Of course your users will have to be very very careful. > > You can improve and to create small wrappers around classes in Python > that checks preconditions. > > Another approach is to expose "Pythonic" API, but it has its price and > this is not cheep. I suggest you to go > with the first one. > > > #include <iostream> > > > > class Bob{ > > public: > > char *fred; > > char *planet; > > double image[10]; > > double *data[2]; > > > > Bob(){ > > planet="Naboo"; > > > > for(int i=0; i<10; i++) image[i]=i; > > > > data[0] = new double[5]; > > data[1] = new double[5]; > > for(int i=0; i<5; i++){ > > data[0][i] = 5-i; > > data[1][i] = i+5; > > } > > } > > > > void getName(char *buff, int len){ > > strncpy(buff, "bob", len); > > } > > > > int loadFile(char *name){ > > // do stuff > > return 0; > > } > > }; > > > > int main(int argc, char **argv){ > > Bob *bob = new Bob(); > > std::cout << "bob->planet = " << bob->planet << std::endl; > > > > bob->fred = "ABC"; > > std::cout << "bob->fred = " << bob->fred << std::endl; > > > > char buff[10]; > > bob->getName(buff, 10); > > std::cout << "buff = " << buff << std::endl; > > > > std::cout << "bob->image[7] = " << bob->image[7] << std::endl; > > > > std::cout << "bob->data[1][2] = " << bob->data[1][2] << std::endl; > > > > std::cout << "bob->loadFile = " << bob->loadFile("data.dat") << > > std::endl; > > } > > > > Getting the getName example above going is probably my most pressing need > as > > I need that to get version and status info off the device in order to > verify > > that I do actually have a valid connection. > > Hmm. In this case we can create new function transformation > ( > http://language-binding.net/pyplusplus/documentation/functions/transformation/transformation.html > ) > > It should not be too difficult. > > Another solution is to generate wrapper for such functions and to expose > it. > > > The planet example seems to work fine (you suggested in another mail that > it > > might). > > Good > > > Once I get the fred example going I can probably figure out the the image > > and data ones. > > Consider my advice about ctypes. > > I can patch Py++ today, so instead of exposing the variable it will > expose the variable address: > > mb = module_builder_t( ... ) > mb.var( 'fred' ).expose_address = True > > Better name for property is welcome > > > I haven't tested the loadFile example yet and I consider it low priority. > > I guess "modify_type" function transformation could be used. It is a > little bit ugly > but it will work > > > Also I very much appreciate the help you have been giving me, thank you. > > My pleasure. > > -- > Roman Yakovenko > C++ Python language binding > http://www.language-binding.net/ > |
From: Roman Y. <rom...@gm...> - 2008-07-08 05:02:09
|
On Tue, Jul 8, 2008 at 4:47 AM, Gordon Wrigley <gor...@gm...> wrote: > This is about the size right? If so is it going to complain about every > pointer variable I have? and if that is the case then why doesn't it just > produce a warning and then assume that if it's not null then the length is > 1, that at least will work for regular pointers. > Or is this just about the combination of the pointer and the array? The combination. Py++ treats pretty well "regular" pointers and provides few call policies for convenience: http://language-binding.net/pyplusplus/documentation/functions/call_policies.html#py-defined-call-policies -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Roman Y. <rom...@gm...> - 2008-07-08 05:00:26
|
On Tue, Jul 8, 2008 at 4:31 AM, Gordon Wrigley <gor...@gm...> wrote: > OK, that seems to make some sense, but leads to a few lil feature requests. > > First the py++ code on that page is overly verbose, it would be nice if this > could be handled in one line. So for this C++ code: > > class tom > { > public: > double *data; > double dataLen; > > you might have something like: > > mb.class_( "tom" ).variable( "data" ).size("tom.dataLen") > > I realise it's probably not going to be quite that simple, I'm just trying > to convey the direction of the idea. Interesting idea. I will try it. > Also if you had a standard policy of > always having a xLen variable for every x pointer variable (or xLen function > for every function returning a pointer) then it'd be nice to be able to > capture that in a single line. > > And of course this would all have to be extended somehow to work with my > array of pointers example and the documentations width*heigh example. :-). Adding support for 2 dimensions array is on my todo list. > Also that warning that py++ should give when it runs into one of these > should include an example of the sort of line required to fix it. I will fix it before next release -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Roman Y. <rom...@gm...> - 2008-07-08 04:55:39
|
On Tue, Jul 8, 2008 at 5:03 AM, Gordon Wrigley <gor...@gm...> wrote: > I think I found another bug, but I'm not sure who's bug it is. This: > > class Alpha > { > private: > class Omega > { > <snip> > } > > public: > Omega *pOmega; > } > > produces: > > static ::Alpha::Omega * get_pOmega(Alpha const & inst ){ > return inst.pOmega; > } > > which leads to: > > extending.cpp(634) : error C2248: 'Alpha::Omega' : cannot access private > class declared in class 'Alpha' > c:\program > files\boost\boost_1_35_0\libs\python\example\bobit.h(1458) : see declaration > of 'Alpha::Omega' > c:\program > files\boost\boost_1_35_0\libs\python\example\bobit.h(1223) : see declaration > of 'Alpha' The example you posted could not be compiled with gccxml: The error is: Error occured during code generation process! Error: Error occured while running GCC-XML: d:\tmp\yyy.h: In function 'Alpha::Omega* get_pOmega(const Alpha&)': d:\tmp\yyy.h:5: error: 'class Alpha::Omega' is private d:\tmp\yyy.h:11: error: within this context I guess the actual code looks like: class Alpha { private: class Omega {}; public: typedef Omega Om; public: Omega *pOmega; }; static ::Alpha::Om * get_pOmega(Alpha const & inst ){ return inst.pOmega; } Now these are the warning I've got during the code generation process: > warning W1025: Py++ will generate class wrapper - class contains > "pOmega" - T* member variable WARNING: Alpha::Omega * get_pOmega(Alpha const & inst) [free function] > compilation error W1005: Py++ cannot expose function that takes as > argument/returns instance of non-public class. Generated code will not > compile. WARNING: Alpha::Omega * get_pOmega(Alpha const & inst) [free function] > compilation error W1050: The function returns "Alpha::Omega *" type. > You have to specify a call policies.Be sure to take a look on Py++ > defined call policies: http://language- > binding.net/pyplusplus/documentation/functions/call_policies.html#py- > defined-call-policies WARNING: Alpha::Omega [class] > execution error W1040: The declaration is unexposed, but there are > other declarations, which refer to it. This could cause "no to_python > converter found" run time error. Declarations: Alpha::pOmega > [variable] The last warning warns you about that. Now you can decide what you want to do. In my opinion this is just a mistake in the code, but I could be wrong. Anyway if you want to exclude declarations, based on warnings they produce, you can do this too: http://language-binding.net/pyplusplus/documentation/warnings.html HTH -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Gordon W. <gor...@gm...> - 2008-07-08 02:03:29
|
I think I found another bug, but I'm not sure who's bug it is. This: class Alpha { private: class Omega { <snip> } public: Omega *pOmega; } produces: static ::Alpha::Omega * get_pOmega(Alpha const & inst ){ return inst.pOmega; } which leads to: extending.cpp(634) : error C2248: 'Alpha::Omega' : cannot access private class declared in class 'Alpha' c:\program files\boost\boost_1_35_0\libs\python\example\bobit.h(1458) : see declaration of 'Alpha::Omega' c:\program files\boost\boost_1_35_0\libs\python\example\bobit.h(1223) : see declaration of 'Alpha' On Tue, Jul 8, 2008 at 11:47 AM, Gordon Wrigley <gor...@gm...> wrote: > This is about the size right? If so is it going to complain about every > pointer variable I have? and if that is the case then why doesn't it just > produce a warning and then assume that if it's not null then the length is > 1, that at least will work for regular pointers. > Or is this just about the combination of the pointer and the array? > > > On Tue, Jul 8, 2008 at 11:31 AM, Gordon Wrigley <gor...@gm...> > wrote: > >> OK, that seems to make some sense, but leads to a few lil feature >> requests. >> >> First the py++ code on that page is overly verbose, it would be nice if >> this could be handled in one line. So for this C++ code: >> >> class tom >> { >> public: >> double *data; >> double dataLen; >> >> you might have something like: >> >> mb.class_( "tom" ).variable( "data" ).size("tom.dataLen") >> >> I realise it's probably not going to be quite that simple, I'm just trying >> to convey the direction of the idea. Also if you had a standard policy of >> always having a xLen variable for every x pointer variable (or xLen function >> for every function returning a pointer) then it'd be nice to be able to >> capture that in a single line. >> >> And of course this would all have to be extended somehow to work with my >> array of pointers example and the documentations width*heigh example. >> >> Also that warning that py++ should give when it runs into one of these >> should include an example of the sort of line required to fix it. >> >> :) >> >> Gordon. >> >> >> On Mon, Jul 7, 2008 at 6:51 PM, Roman Yakovenko < >> rom...@gm...> wrote: >> >>> On Mon, Jul 7, 2008 at 10:28 AM, Gordon Wrigley >>> <gor...@gm...> wrote: >>> > Disclaimer: I have no idea what I'm doing and C++ is not one of my >>> strong >>> > skills. I'm having a problem with py++, boost, msvc and a third party >>> > library I need to bridge to python. I would greatly appreciate any help >>> I >>> > can get with this. >>> >>> :-) >>> >>> > I don't have the various version information handy but I downloaded all >>> of >>> > the boost/py++/msvc stuff from the relevant websites last week. After I >>> > installed everything I made it compile and run the quick start example >>> > correctly. >>> > >>> > I ran the library header through the py++ gui, grabbed the py++ code >>> that >>> > generated, put it in a .py file, ran that and then copied the resulting >>> > files into the quick start example. >>> > >>> > The header for the library includes this snippet (details obscured to >>> > protect the guilty): >>> > >>> > class bob >>> > { >>> > public: >>> > double *fred[4]; >>> >>> This is a bug in Py++. >>> >>> The code generated for "double* fred[4]" caused the compilation error. >>> It is not possible to generate code for "fred" without knowing >>> additional details. In this case Py++ has to exclude this variable >>> from being exposed and give some warning. >>> >>> Now, how can you improve the situation: >>> * exclude variable by your own >>> * take a look on "return_range" ( >>> >>> http://language-binding.net/pyplusplus/documentation/functions/call_policies.html#return-range >>> ) call policies. >>> >>> HTH >>> >>> -- >>> Roman Yakovenko >>> C++ Python language binding >>> http://www.language-binding.net/ >>> >> >> > |
From: Gordon W. <gor...@gm...> - 2008-07-08 01:47:23
|
This is about the size right? If so is it going to complain about every pointer variable I have? and if that is the case then why doesn't it just produce a warning and then assume that if it's not null then the length is 1, that at least will work for regular pointers. Or is this just about the combination of the pointer and the array? On Tue, Jul 8, 2008 at 11:31 AM, Gordon Wrigley <gor...@gm...> wrote: > OK, that seems to make some sense, but leads to a few lil feature requests. > > First the py++ code on that page is overly verbose, it would be nice if > this could be handled in one line. So for this C++ code: > > class tom > { > public: > double *data; > double dataLen; > > you might have something like: > > mb.class_( "tom" ).variable( "data" ).size("tom.dataLen") > > I realise it's probably not going to be quite that simple, I'm just trying > to convey the direction of the idea. Also if you had a standard policy of > always having a xLen variable for every x pointer variable (or xLen function > for every function returning a pointer) then it'd be nice to be able to > capture that in a single line. > > And of course this would all have to be extended somehow to work with my > array of pointers example and the documentations width*heigh example. > > Also that warning that py++ should give when it runs into one of these > should include an example of the sort of line required to fix it. > > :) > > Gordon. > > > On Mon, Jul 7, 2008 at 6:51 PM, Roman Yakovenko <rom...@gm...> > wrote: > >> On Mon, Jul 7, 2008 at 10:28 AM, Gordon Wrigley >> <gor...@gm...> wrote: >> > Disclaimer: I have no idea what I'm doing and C++ is not one of my >> strong >> > skills. I'm having a problem with py++, boost, msvc and a third party >> > library I need to bridge to python. I would greatly appreciate any help >> I >> > can get with this. >> >> :-) >> >> > I don't have the various version information handy but I downloaded all >> of >> > the boost/py++/msvc stuff from the relevant websites last week. After I >> > installed everything I made it compile and run the quick start example >> > correctly. >> > >> > I ran the library header through the py++ gui, grabbed the py++ code >> that >> > generated, put it in a .py file, ran that and then copied the resulting >> > files into the quick start example. >> > >> > The header for the library includes this snippet (details obscured to >> > protect the guilty): >> > >> > class bob >> > { >> > public: >> > double *fred[4]; >> >> This is a bug in Py++. >> >> The code generated for "double* fred[4]" caused the compilation error. >> It is not possible to generate code for "fred" without knowing >> additional details. In this case Py++ has to exclude this variable >> from being exposed and give some warning. >> >> Now, how can you improve the situation: >> * exclude variable by your own >> * take a look on "return_range" ( >> >> http://language-binding.net/pyplusplus/documentation/functions/call_policies.html#return-range >> ) call policies. >> >> HTH >> >> -- >> Roman Yakovenko >> C++ Python language binding >> http://www.language-binding.net/ >> > > |
From: Gordon W. <gor...@gm...> - 2008-07-08 01:30:54
|
OK, that seems to make some sense, but leads to a few lil feature requests. First the py++ code on that page is overly verbose, it would be nice if this could be handled in one line. So for this C++ code: class tom { public: double *data; double dataLen; you might have something like: mb.class_( "tom" ).variable( "data" ).size("tom.dataLen") I realise it's probably not going to be quite that simple, I'm just trying to convey the direction of the idea. Also if you had a standard policy of always having a xLen variable for every x pointer variable (or xLen function for every function returning a pointer) then it'd be nice to be able to capture that in a single line. And of course this would all have to be extended somehow to work with my array of pointers example and the documentations width*heigh example. Also that warning that py++ should give when it runs into one of these should include an example of the sort of line required to fix it. :) Gordon. On Mon, Jul 7, 2008 at 6:51 PM, Roman Yakovenko <rom...@gm...> wrote: > On Mon, Jul 7, 2008 at 10:28 AM, Gordon Wrigley > <gor...@gm...> wrote: > > Disclaimer: I have no idea what I'm doing and C++ is not one of my strong > > skills. I'm having a problem with py++, boost, msvc and a third party > > library I need to bridge to python. I would greatly appreciate any help I > > can get with this. > > :-) > > > I don't have the various version information handy but I downloaded all > of > > the boost/py++/msvc stuff from the relevant websites last week. After I > > installed everything I made it compile and run the quick start example > > correctly. > > > > I ran the library header through the py++ gui, grabbed the py++ code that > > generated, put it in a .py file, ran that and then copied the resulting > > files into the quick start example. > > > > The header for the library includes this snippet (details obscured to > > protect the guilty): > > > > class bob > > { > > public: > > double *fred[4]; > > This is a bug in Py++. > > The code generated for "double* fred[4]" caused the compilation error. > It is not possible to generate code for "fred" without knowing > additional details. In this case Py++ has to exclude this variable > from being exposed and give some warning. > > Now, how can you improve the situation: > * exclude variable by your own > * take a look on "return_range" ( > > http://language-binding.net/pyplusplus/documentation/functions/call_policies.html#return-range > ) call policies. > > HTH > > -- > Roman Yakovenko > C++ Python language binding > http://www.language-binding.net/ > |
From: Roman Y. <rom...@gm...> - 2008-07-07 19:37:01
|
On Mon, Jul 7, 2008 at 10:17 PM, Damien Fagnou <dam...@mo...> wrote: > there is an other issue that I have been wondering how to solve . Please start another thread. > our lib use IMath Internally to store and manipulate math objects ( vector , > matrix , etc ) > I could;t find boostBinding of Imath , I guess we are gonna try to create > one using lovely py++ but in the mean > time we already have wrapper for those class for our other binding to Lua ( > Vector , Matrix etc ) > > those type easy construct with there repective Imath Type . > > my question is if I have a methode like > > void setTransform( Imath::m44f & mat ); > > > could I define automatic converter like : > > bp::converter< Mattrix , Imath::m44f , myConvertionFunction > > > maybe this is more a boostPython question ? > I am kindda new to that too ;) I am not sure I understand you. It seems to me that you are looking for next document: http://www.boost.org/doc/libs/1_35_0/libs/python/doc/v2/implicit.html#implicitly_convertible-spec > and then how would I register that to py++ , using the > add_code_registration() ? If you will find solution it will not be a problem to integrate it with generated code: http://language-binding.net/pyplusplus/documentation/inserting_code.html -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Ben S. <bsc...@lu...> - 2008-07-07 19:17:03
|
Please note that the way gcc works for FIELDs and ENUMs isn't too great. After a lot of experimentation, I discovered that __attribute() has to appear after the field and enum declaration. It can appear before for methods and classes. Thats why the META_FIELD and META_ENUM are written the way they are. The parser I wrote firsts finds the declaration __META_FIELD_FUNCTION and then looks for a field with the same or after line number. If it finds one, then that field is considered to have that annotation. If you are willing to give into gccxml's bug (feature?) and only put META_FIELD after the declaration, then META_FIELD's implementation doesn't have to be so complex and will be more robust. Cheers Ben ________________________________ From: Damien Fagnou [mailto:dam...@mo...] Sent: Monday, July 07, 2008 12:04 PM To: Ben Schleimer; Roman Yakovenko Cc: pyg...@li... Subject: RE: [pygccxml-development] Tag for Methods to bind ? Looks great !! thanks a lot for sharing that ! I will try it when I get to the office tomorow . damien -----Original Message----- From: Ben Schleimer [mailto:bsc...@lu...] Sent: Mon 7/7/2008 7:46 PM To: Roman Yakovenko Cc: Damien Fagnou; pyg...@li... Subject: RE: [pygccxml-development] Tag for Methods to bind ? I just found the code. -------------------------------------------- #ifndef PREPROCESS // This forces the class to have a virtual table so definition system works correctly #define META_CLASS(...) virtual void __META_CLASS_FUNCTION__(void) {}; #define META_FIELD(...) // #define META_METHOD(...) #define META_ENUM(...) #define META_INFO(key, value) #define META_PROPERTY(...) #else // Define the macros as nothing #define META_CLASS(x) __attribute__((gccxml("META_CLASS", #x))) \ virtual void __META_CLASS_FUNCTION__(void); // These multiple definitions of helper are intended to allow each META_INFO // line appear as a unique declaration to the compiler #define META_FIELD(x) META_FIELD_HELPER(__LINE__, x) #define META_FIELD_HELPER(line, x) META_FIELD_HELPER2(line, x) #define META_FIELD_HELPER2(line, x) \ __attribute__((gccxml("META_FIELD", #x))) \ void __META_FIELD_FUNCTION__ ## line () {}; #define META_METHOD(x) __attribute__((gccxml("META_METHOD", #x))) #define META_ENUM(x) META_ENUM_HELPER(__LINE__, x) #define META_ENUM_HELPER(line, x) META_ENUM_HELPER2(line, x) #define META_ENUM_HELPER2(line, x) \ __attribute__((gccxml("META_ENUM", #x))) \ void __META_ENUM_FUNCTION__ ## line () {}; #define META_INFO(key, value) META_INFO_HELPER(__LINE__, key, value) #define META_INFO_HELPER(line, key, value) META_INFO_HELPER2(line, key, value) #define META_INFO_HELPER2(line, key, value) \ __attribute__((gccxml("META_INFO", key, value))) \ void __META_INFO_FUNCTION__ ## line () {}; #define META_PROPERTY(x) META_PROPERTY_HELPER(__LINE__, x) #define META_PROPERTY_HELPER(line, x) META_PROPERTY_HELPER2(line, x) #define META_PROPERTY_HELPER2(line, x) \ __attribute__((gccxml("META_PROPERTY", #x))) \ void __META_PROPERTY_FUNCTION__ ## line () {}; #endif ---------------------------------------------- class Foo { META_CLASS(CLASS INFO HERE); META_INFO("Class Type", "This is info separated by spaces"); META_INFO("MY_COMPANY_SPECIFIC_INFO_NOTICE", "Some info here.."); META_INFO("DOC", "Class Documentation here.."); // These are Qt style property declarations. META_PROPERTY(int Foo); META_PROPERTY(string Name READONLY DOC "This is the name property of this"); // These fields is not exported void* nulptr; int baz; // These fields are exported META_FIELD(NODEF NOREFLECT VALUE="1,1,1") Vec3 foo; META_FIELD(NODEF DOC "This is the bar,:. field") int bar; // Exported META_METHOD(NODEF NOOID DOC "gfg") int doIt() const { return 4*3+12; } // Not exported int fooIt() { } // We can even export enums!! Yeah! META_ENUM(NOOID) enum colors { red, blue, green } ; } ----------------------------------------------------- I was really, really happy with this approach but it couldn't happen (yet!) for various reasons. :( Cheers Ben > -----Original Message----- > From: Roman Yakovenko [mailto:rom...@gm...] > Sent: Monday, July 07, 2008 11:23 AM > To: Ben Schleimer > Cc: Damien Fagnou; pyg...@li... > Subject: Re: [pygccxml-development] Tag for Methods to bind ? > > On Mon, Jul 7, 2008 at 9:14 PM, Ben Schleimer > <bsc...@lu...> wrote: > > I had this same idea. Instead of putting the annotations inside the > > comments, I made Qt style macros which I prepended to my > > function/enum/field declarations. > > > > Something like > > META_CLASS() class A { > > META_METHOD() APtr create(); > > > > // No annotations before this one so it isn't exposed > > float * getInternals(); > > > > .... > > } > > > > The macros turn into __attribute((gccxml("META_XXX"))); > > when a preprocessor flag is defined and turns into nothing > otherwise. > > The cool thing is that you can have additional annotations work by > > using macro inlining... I can't find the code anymore but > it did work... > > You are right, this is another valid option. > Every declarations contains "attributes" property wchih gives > you access to them ( > http://language-binding.net/pyplusplus/documentation/apidocs/p > ygccxml.declarations.declaration.declaration_t-class.html#attributes > ) > > This approach has speed advantage and it is less error prone. > > -- > Roman Yakovenko > C++ Python language binding > http://www.language-binding.net/ > > |
From: Damien F. <dam...@mo...> - 2008-07-07 19:16:16
|
there is an other issue that I have been wondering how to solve . our lib use IMath Internally to store and manipulate math objects ( vector , matrix , etc ) I could;t find boostBinding of Imath , I guess we are gonna try to create one using lovely py++ but in the mean time we already have wrapper for those class for our other binding to Lua ( Vector , Matrix etc ) those type easy construct with there repective Imath Type . my question is if I have a methode like void setTransform( Imath::m44f & mat ); could I define automatic converter like : bp::converter< Mattrix , Imath::m44f , myConvertionFunction > maybe this is more a boostPython question ? I am kindda new to that too ;) and then how would I register that to py++ , using the add_code_registration() ? thanks Damien -----Original Message----- From: Roman Yakovenko [mailto:rom...@gm...] Sent: Mon 7/7/2008 7:57 PM To: Ben Schleimer Cc: Damien Fagnou; pyg...@li... Subject: Re: [pygccxml-development] Tag for Methods to bind ? On Mon, Jul 7, 2008 at 9:46 PM, Ben Schleimer <bsc...@lu...> wrote: > I just found the code. >... > I was really, really happy with this approach but it couldn't happen > (yet!) for various reasons. :( If it is not a secret can you share them? Thank you. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Damien F. <dam...@mo...> - 2008-07-07 19:04:11
|
Looks great !! thanks a lot for sharing that ! I will try it when I get to the office tomorow . damien -----Original Message----- From: Ben Schleimer [mailto:bsc...@lu...] Sent: Mon 7/7/2008 7:46 PM To: Roman Yakovenko Cc: Damien Fagnou; pyg...@li... Subject: RE: [pygccxml-development] Tag for Methods to bind ? I just found the code. -------------------------------------------- #ifndef PREPROCESS // This forces the class to have a virtual table so definition system works correctly #define META_CLASS(...) virtual void __META_CLASS_FUNCTION__(void) {}; #define META_FIELD(...) // #define META_METHOD(...) #define META_ENUM(...) #define META_INFO(key, value) #define META_PROPERTY(...) #else // Define the macros as nothing #define META_CLASS(x) __attribute__((gccxml("META_CLASS", #x))) \ virtual void __META_CLASS_FUNCTION__(void); // These multiple definitions of helper are intended to allow each META_INFO // line appear as a unique declaration to the compiler #define META_FIELD(x) META_FIELD_HELPER(__LINE__, x) #define META_FIELD_HELPER(line, x) META_FIELD_HELPER2(line, x) #define META_FIELD_HELPER2(line, x) \ __attribute__((gccxml("META_FIELD", #x))) \ void __META_FIELD_FUNCTION__ ## line () {}; #define META_METHOD(x) __attribute__((gccxml("META_METHOD", #x))) #define META_ENUM(x) META_ENUM_HELPER(__LINE__, x) #define META_ENUM_HELPER(line, x) META_ENUM_HELPER2(line, x) #define META_ENUM_HELPER2(line, x) \ __attribute__((gccxml("META_ENUM", #x))) \ void __META_ENUM_FUNCTION__ ## line () {}; #define META_INFO(key, value) META_INFO_HELPER(__LINE__, key, value) #define META_INFO_HELPER(line, key, value) META_INFO_HELPER2(line, key, value) #define META_INFO_HELPER2(line, key, value) \ __attribute__((gccxml("META_INFO", key, value))) \ void __META_INFO_FUNCTION__ ## line () {}; #define META_PROPERTY(x) META_PROPERTY_HELPER(__LINE__, x) #define META_PROPERTY_HELPER(line, x) META_PROPERTY_HELPER2(line, x) #define META_PROPERTY_HELPER2(line, x) \ __attribute__((gccxml("META_PROPERTY", #x))) \ void __META_PROPERTY_FUNCTION__ ## line () {}; #endif ---------------------------------------------- class Foo { META_CLASS(CLASS INFO HERE); META_INFO("Class Type", "This is info separated by spaces"); META_INFO("MY_COMPANY_SPECIFIC_INFO_NOTICE", "Some info here.."); META_INFO("DOC", "Class Documentation here.."); // These are Qt style property declarations. META_PROPERTY(int Foo); META_PROPERTY(string Name READONLY DOC "This is the name property of this"); // These fields is not exported void* nulptr; int baz; // These fields are exported META_FIELD(NODEF NOREFLECT VALUE="1,1,1") Vec3 foo; META_FIELD(NODEF DOC "This is the bar,:. field") int bar; // Exported META_METHOD(NODEF NOOID DOC "gfg") int doIt() const { return 4*3+12; } // Not exported int fooIt() { } // We can even export enums!! Yeah! META_ENUM(NOOID) enum colors { red, blue, green } ; } ----------------------------------------------------- I was really, really happy with this approach but it couldn't happen (yet!) for various reasons. :( Cheers Ben > -----Original Message----- > From: Roman Yakovenko [mailto:rom...@gm...] > Sent: Monday, July 07, 2008 11:23 AM > To: Ben Schleimer > Cc: Damien Fagnou; pyg...@li... > Subject: Re: [pygccxml-development] Tag for Methods to bind ? > > On Mon, Jul 7, 2008 at 9:14 PM, Ben Schleimer > <bsc...@lu...> wrote: > > I had this same idea. Instead of putting the annotations inside the > > comments, I made Qt style macros which I prepended to my > > function/enum/field declarations. > > > > Something like > > META_CLASS() class A { > > META_METHOD() APtr create(); > > > > // No annotations before this one so it isn't exposed > > float * getInternals(); > > > > .... > > } > > > > The macros turn into __attribute((gccxml("META_XXX"))); > > when a preprocessor flag is defined and turns into nothing > otherwise. > > The cool thing is that you can have additional annotations work by > > using macro inlining... I can't find the code anymore but > it did work... > > You are right, this is another valid option. > Every declarations contains "attributes" property wchih gives > you access to them ( > http://language-binding.net/pyplusplus/documentation/apidocs/p > ygccxml.declarations.declaration.declaration_t-class.html#attributes > ) > > This approach has speed advantage and it is less error prone. > > -- > Roman Yakovenko > C++ Python language binding > http://www.language-binding.net/ > > |
From: Roman Y. <rom...@gm...> - 2008-07-07 18:56:53
|
On Mon, Jul 7, 2008 at 9:46 PM, Ben Schleimer <bsc...@lu...> wrote: > I just found the code. >... > I was really, really happy with this approach but it couldn't happen > (yet!) for various reasons. :( If it is not a secret can you share them? Thank you. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Ben S. <bsc...@lu...> - 2008-07-07 18:46:53
|
I just found the code. -------------------------------------------- #ifndef PREPROCESS // This forces the class to have a virtual table so definition system works correctly #define META_CLASS(...) virtual void __META_CLASS_FUNCTION__(void) {}; #define META_FIELD(...) // #define META_METHOD(...) #define META_ENUM(...) #define META_INFO(key, value) #define META_PROPERTY(...) #else // Define the macros as nothing #define META_CLASS(x) __attribute__((gccxml("META_CLASS", #x))) \ virtual void __META_CLASS_FUNCTION__(void); // These multiple definitions of helper are intended to allow each META_INFO // line appear as a unique declaration to the compiler #define META_FIELD(x) META_FIELD_HELPER(__LINE__, x) #define META_FIELD_HELPER(line, x) META_FIELD_HELPER2(line, x) #define META_FIELD_HELPER2(line, x) \ __attribute__((gccxml("META_FIELD", #x))) \ void __META_FIELD_FUNCTION__ ## line () {}; #define META_METHOD(x) __attribute__((gccxml("META_METHOD", #x))) #define META_ENUM(x) META_ENUM_HELPER(__LINE__, x) #define META_ENUM_HELPER(line, x) META_ENUM_HELPER2(line, x) #define META_ENUM_HELPER2(line, x) \ __attribute__((gccxml("META_ENUM", #x))) \ void __META_ENUM_FUNCTION__ ## line () {}; #define META_INFO(key, value) META_INFO_HELPER(__LINE__, key, value) #define META_INFO_HELPER(line, key, value) META_INFO_HELPER2(line, key, value) #define META_INFO_HELPER2(line, key, value) \ __attribute__((gccxml("META_INFO", key, value))) \ void __META_INFO_FUNCTION__ ## line () {}; #define META_PROPERTY(x) META_PROPERTY_HELPER(__LINE__, x) #define META_PROPERTY_HELPER(line, x) META_PROPERTY_HELPER2(line, x) #define META_PROPERTY_HELPER2(line, x) \ __attribute__((gccxml("META_PROPERTY", #x))) \ void __META_PROPERTY_FUNCTION__ ## line () {}; #endif ---------------------------------------------- class Foo { META_CLASS(CLASS INFO HERE); META_INFO("Class Type", "This is info separated by spaces"); META_INFO("MY_COMPANY_SPECIFIC_INFO_NOTICE", "Some info here.."); META_INFO("DOC", "Class Documentation here.."); // These are Qt style property declarations. META_PROPERTY(int Foo); META_PROPERTY(string Name READONLY DOC "This is the name property of this"); // These fields is not exported void* nulptr; int baz; // These fields are exported META_FIELD(NODEF NOREFLECT VALUE="1,1,1") Vec3 foo; META_FIELD(NODEF DOC "This is the bar,:. field") int bar; // Exported META_METHOD(NODEF NOOID DOC "gfg") int doIt() const { return 4*3+12; } // Not exported int fooIt() { } // We can even export enums!! Yeah! META_ENUM(NOOID) enum colors { red, blue, green } ; } ----------------------------------------------------- I was really, really happy with this approach but it couldn't happen (yet!) for various reasons. :( Cheers Ben > -----Original Message----- > From: Roman Yakovenko [mailto:rom...@gm...] > Sent: Monday, July 07, 2008 11:23 AM > To: Ben Schleimer > Cc: Damien Fagnou; pyg...@li... > Subject: Re: [pygccxml-development] Tag for Methods to bind ? > > On Mon, Jul 7, 2008 at 9:14 PM, Ben Schleimer > <bsc...@lu...> wrote: > > I had this same idea. Instead of putting the annotations inside the > > comments, I made Qt style macros which I prepended to my > > function/enum/field declarations. > > > > Something like > > META_CLASS() class A { > > META_METHOD() APtr create(); > > > > // No annotations before this one so it isn't exposed > > float * getInternals(); > > > > .... > > } > > > > The macros turn into __attribute((gccxml("META_XXX"))); > > when a preprocessor flag is defined and turns into nothing > otherwise. > > The cool thing is that you can have additional annotations work by > > using macro inlining... I can't find the code anymore but > it did work... > > You are right, this is another valid option. > Every declarations contains "attributes" property wchih gives > you access to them ( > http://language-binding.net/pyplusplus/documentation/apidocs/p > ygccxml.declarations.declaration.declaration_t-class.html#attributes > ) > > This approach has speed advantage and it is less error prone. > > -- > Roman Yakovenko > C++ Python language binding > http://www.language-binding.net/ > > |