From rwgk at yahoo.com Mon Mar 1 05:39:48 2010 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Sun, 28 Feb 2010 20:39:48 -0800 (PST) Subject: [C++-sig] profiling python extension In-Reply-To: <382d227f1002281333g534595e5i6d7408fe129a4730@mail.gmail.com> References: <382d227f1002271952p25858f1eyeb1c495bd282f2b@mail.gmail.com> <382d227f1002281333g534595e5i6d7408fe129a4730@mail.gmail.com> Message-ID: <222034.90586.qm@web111416.mail.gq1.yahoo.com> > The only inconvenience is that I need to start and finish it only being a root. This means > I either have to switch back and forth oftenly or do all profiling (and development as a root). I'm in an environment with relatively few users which I fully trust. To get around the inconvenience I run the script below which installs two set-user-id-root commands "opcontrol_start" and "opcontrol_shutdown". Ralf #! /bin/csh -f set verbose gcc -o setuid_linux setuid_linux.c cp setuid_linux /usr/bin/opcontrol_start mv setuid_linux /usr/bin/opcontrol_shutdown cat << EOT > /usr/bin/opcontrol_start.script #! /bin/bash -r set -v opcontrol --reset; opcontrol --start EOT cat << EOT > /usr/bin/opcontrol_shutdown.script #! /bin/bash -r set -v opcontrol --shutdown EOT chmod 6711 /usr/bin/opcontrol_start /usr/bin/opcontrol_shutdown chmod 755 /usr/bin/opcontrol_start.script /usr/bin/opcontrol_shutdown.script opcontrol --no-vmlinux % cat setuid_linux.c #include #include #include #include #include static char **cpargv(int argc, char *argv[], const char *cmd_name) { int i; char **cargv; cargv = malloc((argc + 1) * sizeof (*cargv)); if (cargv == NULL) return NULL; cargv[0] = (char *) cmd_name; for (i = 1; i < argc; i++) cargv[i] = argv[i]; cargv[i] = NULL; return cargv; } static const char *StripFileName(const char *PathName, int Separator) { const char *FileName; for (FileName = PathName; *PathName; PathName++) if (*PathName == Separator) FileName = PathName + 1; return FileName; } static const char *TrustedCommands[] = { "opcontrol_start", "opcontrol_shutdown", NULL }; int main(int argc, char *argv[]) { const char *progn, **tc, *cmd_dir, *cmd_ext; char *cmd_path, **run_cmd_argv; int n; progn = StripFileName(argv[0], '/'); for (tc = TrustedCommands; *tc; tc++) if (strcmp(progn, *tc) == 0) break; if (*tc == NULL) { fprintf(stderr, "%s: Not a trusted command.\n", progn); exit(1); } if (setuid(0) != 0) { perror(progn); exit(1); } if (setgid(0) != 0) { perror(progn); exit(1); } run_cmd_argv = cpargv(argc, argv, progn); if (run_cmd_argv == NULL) { fprintf(stderr, "%s: Not enough core.\n", progn); exit(1); } cmd_dir = "/usr/bin/"; cmd_ext = ".script"; n = strlen(cmd_dir) + strlen(progn) + strlen(cmd_ext) + 1; cmd_path = malloc(n * sizeof (*cmd_path)); if (cmd_path == NULL) { fprintf(stderr, "%s: Not enough core.\n", progn); exit(1); } strcpy(cmd_path, cmd_dir); strcat(cmd_path, progn); strcat(cmd_path, cmd_ext); (void) execv(cmd_path, run_cmd_argv); perror(progn); exit (1); return 0; } From j.reid at mail.cryst.bbk.ac.uk Mon Mar 1 09:54:19 2010 From: j.reid at mail.cryst.bbk.ac.uk (John Reid) Date: Mon, 01 Mar 2010 08:54:19 +0000 Subject: [C++-sig] profiling python extension In-Reply-To: <382d227f1002281333g534595e5i6d7408fe129a4730@mail.gmail.com> References: <382d227f1002271952p25858f1eyeb1c495bd282f2b@mail.gmail.com> <382d227f1002281333g534595e5i6d7408fe129a4730@mail.gmail.com> Message-ID: Alexey Akimov wrote: > Thank you John, > > I just installed the tool you suggested and tried to use it. However I > do not see any output. Could you give some more detailes of how the > profiling process with the google-profiler should look like? > What I do is: > > 1) bjam variant=profile toolset=gcc cxxflags=-fno-for-scope > linkflags=-lprofiler test_ext > > 2) env CPUPROFILE=/path/to/my/dir/out.prof python ./mypythonscript.py > > This runs my python script which invokes the extension. However it does > not produce any output files (which i expect to be out.prof in my > working directory). What should I do in order to see the profiling > information? I use the profiler via explicit calls to ProfilerStart() and ProfilerStop() which I expose through boost.python and call in my python scripts. Then I can start and stop the profiler at will. However from what I can see in the documentation what you've done looks correct as well. I suppose you could ask bjam to show you the link command to check it is using "-lprofiler". From nitroamos at gmail.com Mon Mar 1 21:08:22 2010 From: nitroamos at gmail.com (Amos Anderson) Date: Mon, 1 Mar 2010 12:08:22 -0800 Subject: [C++-sig] incorrect linking to libpython (Dane Springmeyer) Message-ID: <9e910971003011208t4babbeado59e90f896cc68841@mail.gmail.com> > > Message: 2 > Date: Fri, 26 Feb 2010 18:36:16 -0800 > From: Dane Springmeyer > To: Development of Python/C++ integration > Subject: Re: [C++-sig] incorrect linking to libpython > Message-ID: <57569986-7D90-4686-8384-809F8D27FC68 at hailmail.net> > Content-Type: text/plain; charset=US-ASCII; format=flowed; delsp=yes > > Amos, > > I feel your pain, seriously. I've been down many of these paths as well. > > My overall sense is that direct linking of boost to a python > executable may not be necessary, and rather that bjam could use `- > undefined dynamic_lookup`, which will mean that when you import the > python module you've built with boost::python the right version of > python will be dynamically looked up based on the interpreter you are > running. There are certainly potential problems with this route (and > I've only lightly tested so far) but I think it may hold promise. > > More to the point, I've also got into the habit of passing -Z to the > linker to make sure that if the custom python framework is not able to > be linked, ld does not fallback to linking to the "system" or apple > provided python framework and rather throws an error so you know the > exact point things went wrong rather than only later by getting the > dreaded "Version Mismatch" error. > > Failing to link to the /Library or user installed python26 is almost > invariably the case on snow leopard because two copies will exist and > the user installed version won't be preferentially linked with the > normal -L/path/to/dir -lpython2.6 method because 'libpython2.6' is > actually: > > /Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/config/ > libpython2.6.a > > and my sense is the linker will prefer the /usr/lib/libpython2.6.dylib > over that because of the 'a' (even though it is actually, and oddly, a > symlink to the dynamic library at: > > /Library/Frameworks/Python.framework/Versions/2.6/Python > > So, one workaround is symlinking: > > /Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/config/ > libpython2.6.dylib ?-> ../../../Python > > Then bjam should be able to find it. > > But I think a preferable method would be if bjam actually sent the > linker line: > > -F/Library/Library/Frameworks -framework Python -Z > > instead of -L/etc/etc -lpython... > > > Dane > > > More info on those ld commands at: > http://developer.apple.com/mac/library/DOCUMENTATION/Darwin/Reference/ManPages/man1/ld.1.html I can confirm that your solution fixed the problem. Actually, I just did this: sudo cp libpython2.6.a libpython2.6.dylib (and recompiled boost python) Thanks! Amos. From nitroamos at gmail.com Tue Mar 2 02:19:30 2010 From: nitroamos at gmail.com (Amos Anderson) Date: Mon, 1 Mar 2010 17:19:30 -0800 Subject: [C++-sig] boost python constructor for tr1::array Message-ID: <9e910971003011719w31ccca2bj7059e70837182285@mail.gmail.com> Hello -- i've got a wrapper for a tr1::array, but i don't know how to make a constructor for it. i have something like: //some stuff defining functions //... class_ > (ss.str().c_str()) .def("__getitem__", get, return_value_policy()) .def("__setitem__", &array_setitem) .def("__iter__", range > (vecbegin, vecend)) ; where the name will end up being something like "Array2_double". In my python code right now, I have do to something like this: pair = Array2_double() pair[0] = 0.1 pair[1] = 1.2 But I'd like to do this: pair = Array2_double(0.1, 1.2) or even better: listOfPairs = Vector_Array2_double() listOfPairs.append(0.1, 1.2) i've been able to follow the tutorials etc for simple classes, but nothing i've tried for this will compile. well, i know i could make an external function: pair = make_Array2_double(0.1,1.2) if i really wanted to, but i don't know how to do this within templates, so i think i'd have to make all those separately. thanks! Amos. From p_goel at coverify.net Tue Mar 2 12:09:49 2010 From: p_goel at coverify.net (puneet goel) Date: Tue, 2 Mar 2010 16:39:49 +0530 Subject: [C++-sig] Boost Python: C++ struct with a function pointer Message-ID: <30cba3501003020309v2bfde7a0n9610cb5b17506291@mail.gmail.com> Greetings I am boost.python newbie. I tried searching the web for a solution but could not find one. I am trying to generate Python Bindings for a C++ API. The API has some data structures with a set function pointers as its members. struct foo { public: int a, b; char *str; int (*func1) (); int (*func2) (); }; I am wondering if it is possible to bind this struct to Python. Let me know how this can be done. Regards - Puneet From Matthew.Scouten at tradingtechnologies.com Tue Mar 2 19:14:38 2010 From: Matthew.Scouten at tradingtechnologies.com (Matthew Scouten (TT)) Date: Tue, 2 Mar 2010 12:14:38 -0600 Subject: [C++-sig] Boost Python: C++ struct with a function pointer In-Reply-To: <30cba3501003020309v2bfde7a0n9610cb5b17506291@mail.gmail.com> References: <30cba3501003020309v2bfde7a0n9610cb5b17506291@mail.gmail.com> Message-ID: <32490DFF7774554A85D65D23A9F0F9380C7B97DF@chiex01> Not in any straight forward way. C++ function pointers need to exist at compile time, while python functions do not exist till runtime. You might have a few work abounds, depending on use. The most obvious is to hardwire the pointers to known c++ functions that call python functions after some kind of table look up. Another is to create some delegate objects in c++ that have a fnptr data members not exposed to python. Your foo object will then wrap the data members as propertys that take a delegate and extract the fn pointers and visa-versa Implementation is left as an exercise to the student. -----Original Message----- From: cplusplus-sig-bounces+matthew.scouten=tradingtechnologies.com at python.org [mailto:cplusplus-sig-bounces+matthew.scouten=tradingtechnologies.com at py thon.org] On Behalf Of puneet goel Sent: Tuesday, March 02, 2010 5:10 AM To: cplusplus-sig at python.org Subject: [C++-sig] Boost Python: C++ struct with a function pointer Greetings I am boost.python newbie. I tried searching the web for a solution but could not find one. I am trying to generate Python Bindings for a C++ API. The API has some data structures with a set function pointers as its members. struct foo { public: int a, b; char *str; int (*func1) (); int (*func2) (); }; I am wondering if it is possible to bind this struct to Python. Let me know how this can be done. Regards - Puneet _______________________________________________ Cplusplus-sig mailing list Cplusplus-sig at python.org http://mail.python.org/mailman/listinfo/cplusplus-sig From talljimbo at gmail.com Tue Mar 2 21:03:26 2010 From: talljimbo at gmail.com (Jim Bosch) Date: Tue, 02 Mar 2010 12:03:26 -0800 Subject: [C++-sig] Boost Python: C++ struct with a function pointer In-Reply-To: <30cba3501003020309v2bfde7a0n9610cb5b17506291@mail.gmail.com> References: <30cba3501003020309v2bfde7a0n9610cb5b17506291@mail.gmail.com> Message-ID: <1267560206.10737.6.camel@mu> On Tue, 2010-03-02 at 16:39 +0530, puneet goel wrote: > Greetings > > I am boost.python newbie. I tried searching the web for a solution but > could not find one. > I am trying to generate Python Bindings for a C++ API. The API has > some data structures with a set function pointers as its members. > > struct foo { > public: > int a, b; > char *str; > > int (*func1) (); > int (*func2) (); > }; > > I am wondering if it is possible to bind this struct to Python. Let me > know how this can be done. > If you just need your Python interface to support calling those function pointers, not adding new functions in Python, it's relatively easy. In particular, boost::python::make_function takes a C++ function pointer and returns a callable Python, so you can do something like this: namespace bp = boost::python; bp::object foo_get_func1(foo & self) { return bp::make_function(self.func1); } bp::class_("foo") .add_property("func1", foo_get_func1) ; I haven't tested that snippet, so it may need some tweaks. But hopefully it will get you started. Jim Bosch From p_goel at coverify.net Wed Mar 3 03:18:36 2010 From: p_goel at coverify.net (puneet goel) Date: Wed, 3 Mar 2010 07:48:36 +0530 Subject: [C++-sig] Boost Python: C++ struct with a function pointer In-Reply-To: <1267560206.10737.6.camel@mu> References: <30cba3501003020309v2bfde7a0n9610cb5b17506291@mail.gmail.com> <1267560206.10737.6.camel@mu> Message-ID: <30cba3501003021818k78a60db3neb6f75c6056804e8@mail.gmail.com> Mathew/Jim > If you just need your Python interface to support calling those function > pointers, not adding new functions in Python, it's relatively easy. Thanks for your support. Actually I need to pass data from Python to C++. I am required to pass Python functions as part of the structure in a way that these get executed somewhere in C++. Now that I know that this can not be done in a straightforward manner, I am looking for a workaround. I would like to know whether it is at all possible to pass a Python function, as data, to C++ using boost-python. What would be the C++ type of a structure element that would be able to hold a Python function when passed using boost-python? To clarify, if I get the C++ API changed to something like struct foo { public: int a, b; char *str; foobar func1; foobar func2; }; What type (in C++) would foobar be so that I am able to pass a python function for func1 and func2? Regards - Puneet From seefeld at sympatico.ca Wed Mar 3 03:26:31 2010 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Tue, 02 Mar 2010 21:26:31 -0500 Subject: [C++-sig] Boost Python: C++ struct with a function pointer In-Reply-To: <30cba3501003021818k78a60db3neb6f75c6056804e8@mail.gmail.com> References: <30cba3501003020309v2bfde7a0n9610cb5b17506291@mail.gmail.com> <1267560206.10737.6.camel@mu> <30cba3501003021818k78a60db3neb6f75c6056804e8@mail.gmail.com> Message-ID: <4B8DC8D7.5030108@sympatico.ca> On 03/02/2010 09:18 PM, puneet goel wrote: > Mathew/Jim > > >> If you just need your Python interface to support calling those function >> pointers, not adding new functions in Python, it's relatively easy. >> > Thanks for your support. > > Actually I need to pass data from Python to C++. I am required to > pass Python functions as part of the structure in a way that these get > executed somewhere in C++. > > Now that I know that this can not be done in a straightforward manner, > I am looking for a workaround. I'm not sure what you mean by "straightforward" and "workaround". Python functions are objects, as anything else in Python. And to call them, you invoke the operator() on them. Since Python functions are objects, you can pass them around and store them in what I would call a very straightforward way. There is really nothing special about them. > I would like to know whether it is at > all possible to pass a Python function, as data, to C++ using > boost-python. What would be the C++ type of a structure element that > would be able to hold a Python function when passed using > boost-python? > > To clarify, if I get the C++ API changed to something like > > struct foo { > public: > int a, b; > char *str; > > foobar func1; > foobar func2; > }; > > What type (in C++) would foobar be so that I am able to pass a python > function for func1 and func2? > boost::python::object. Stefan -- ...ich hab' noch einen Koffer in Berlin... From talljimbo at gmail.com Wed Mar 3 03:33:48 2010 From: talljimbo at gmail.com (Jim Bosch) Date: Tue, 02 Mar 2010 18:33:48 -0800 Subject: [C++-sig] Boost Python: C++ struct with a function pointer In-Reply-To: <30cba3501003021818k78a60db3neb6f75c6056804e8@mail.gmail.com> References: <30cba3501003020309v2bfde7a0n9610cb5b17506291@mail.gmail.com> <1267560206.10737.6.camel@mu> <30cba3501003021818k78a60db3neb6f75c6056804e8@mail.gmail.com> Message-ID: <1267583628.15537.9.camel@mu> On Wed, 2010-03-03 at 07:48 +0530, puneet goel wrote: > Mathew/Jim > > > If you just need your Python interface to support calling those function > > pointers, not adding new functions in Python, it's relatively easy. > > Thanks for your support. > > Actually I need to pass data from Python to C++. I am required to > pass Python functions as part of the structure in a way that these get > executed somewhere in C++. > > Now that I know that this can not be done in a straightforward manner, > I am looking for a workaround. I would like to know whether it is at > all possible to pass a Python function, as data, to C++ using > boost-python. What would be the C++ type of a structure element that > would be able to hold a Python function when passed using > boost-python? > > To clarify, if I get the C++ API changed to something like > > struct foo { > public: > int a, b; > char *str; > > foobar func1; > foobar func2; > }; > > What type (in C++) would foobar be so that I am able to pass a python > function for func1 and func2? boost::python::object - it's just a smart pointer to an arbitrary Python object (in the Python C-API, it's PyObject*). It overloads operator() to invoke the underlying Python object's __call__ method, and it's templated to take a reasonable number of arbitrarily typed arguments, convert them to Python, and feed them to the Python method. Jim From p_goel at coverify.net Wed Mar 3 03:35:43 2010 From: p_goel at coverify.net (puneet goel) Date: Wed, 3 Mar 2010 08:05:43 +0530 Subject: [C++-sig] Boost Python: C++ struct with a function pointer In-Reply-To: <1267583628.15537.9.camel@mu> References: <30cba3501003020309v2bfde7a0n9610cb5b17506291@mail.gmail.com> <1267560206.10737.6.camel@mu> <30cba3501003021818k78a60db3neb6f75c6056804e8@mail.gmail.com> <1267583628.15537.9.camel@mu> Message-ID: <30cba3501003021835g4159d212u4802eb7f811b8fc9@mail.gmail.com> > boost::python::object - it's just a smart pointer to an arbitrary Python > object (in the Python C-API, it's PyObject*). ?It overloads operator() > to invoke the underlying Python object's __call__ method, and it's > templated to take a reasonable number of arbitrarily typed arguments, > convert them to Python, and feed them to the Python method. > Jim/Stefan. I think now I know how to proceed. Thanks a ton. Regards - Puneet From guillaume at paralint.com Wed Mar 3 20:10:55 2010 From: guillaume at paralint.com (Guillaume Seguin) Date: Wed, 3 Mar 2010 14:10:55 -0500 Subject: [C++-sig] dict.has_key works in a Python script, not in C++ Message-ID: <42d7ad4f1003031110s651524c7t13effb8594dbfba3@mail.gmail.com> I have a C++ object (named hello) exposed in a Python extension using boost::python version 1.42. This code works : import my_ext aaa = my_ext.hello('aaa') d = { aaa:12345 } assert aaa in d #This assertion is true, as expected assert d.has_key(aaa) #This assertion is true, as expected But if I do the same thing on the C++ side, using boost::python::dict::has_key, the is key is never found. #This Python code assert my_ext.find_key(d, aaa) //Calls this C++ code bool find_key(boost::python::dict d, const hello& key_to_find) { return d.has_key(key_to_find); } I defined the operator == like this, but it is never called. bool hello::operator == (const hello &h) const { return country == h.country; } And my boost class is exposed like this : using namespace boost::python; class_("hello", init()) .def(self == self) ; I tried stepping through the code with gdb, but I got lost ... What am I missing ? TIA -- Guillaume -------------- next part -------------- An HTML attachment was scrubbed... URL: From seefeld at sympatico.ca Wed Mar 3 21:35:13 2010 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Wed, 03 Mar 2010 15:35:13 -0500 Subject: [C++-sig] dict.has_key works in a Python script, not in C++ In-Reply-To: <42d7ad4f1003031110s651524c7t13effb8594dbfba3@mail.gmail.com> References: <42d7ad4f1003031110s651524c7t13effb8594dbfba3@mail.gmail.com> Message-ID: <4B8EC801.4020908@sympatico.ca> On 03/03/2010 02:10 PM, Guillaume Seguin wrote: > I have a C++ object (named hello) exposed in a Python extension using > boost::python version 1.42. This code works : > > import my_ext > > aaa = my_ext.hello('aaa') > > d = { aaa:12345 } > > assert aaa in d #This assertion is true, as expected > assert d.has_key(aaa) #This assertion is true, as expected > > But if I do the same thing on the C++ side, using > boost::python::dict::has_key, the is key is never found. > > #This Python code > assert my_ext.find_key(d, aaa) > > //Calls this C++ code > bool find_key(boost::python::dict d, const hello& key_to_find) > { > return d.has_key(key_to_find); > } > > I defined the operator == like this, but it is never called. > > bool hello::operator == (const hello &h) const { > return country == h.country; > } > > And my boost class is exposed like this : > > using namespace boost::python; > class_("hello", init()) > .def(self == self) > ; > > I tried stepping through the code with gdb, but I got lost ... What am > I missing ? TIA Python requires dictionary keys to be immutable. I wouldn't be surprised if it used object identity checks (such as address comparison) instead of a deep equal test, as a faster way to look up objects. Stefan -- ...ich hab' noch einen Koffer in Berlin... From talljimbo at gmail.com Wed Mar 3 23:56:12 2010 From: talljimbo at gmail.com (Jim Bosch) Date: Wed, 03 Mar 2010 14:56:12 -0800 Subject: [C++-sig] dict.has_key works in a Python script, not in C++ In-Reply-To: <4B8EC801.4020908@sympatico.ca> References: <42d7ad4f1003031110s651524c7t13effb8594dbfba3@mail.gmail.com> <4B8EC801.4020908@sympatico.ca> Message-ID: <1267656972.4905.1.camel@bishop> On Wed, 2010-03-03 at 15:35 -0500, Stefan Seefeld wrote: > > > > I tried stepping through the code with gdb, but I got lost ... What am > > I missing ? TIA > > Python requires dictionary keys to be immutable. I wouldn't be surprised > if it used object identity checks (such as address comparison) instead > of a deep equal test, as a faster way to look up objects. > That's exactly what it does, unless your object implements the __hash__ special method. Do that (and in so doing, promise that the return value of __hash__ will never change), and this should work. Jim Bosch From guillaume at paralint.com Thu Mar 4 17:28:53 2010 From: guillaume at paralint.com (Guillaume Seguin) Date: Thu, 4 Mar 2010 11:28:53 -0500 Subject: [C++-sig] dict.has_key works in a Python script, not in C++ In-Reply-To: <42d7ad4f1003031110s651524c7t13effb8594dbfba3@mail.gmail.com> References: <42d7ad4f1003031110s651524c7t13effb8594dbfba3@mail.gmail.com> Message-ID: <42d7ad4f1003040828o4fa733fbk78f8d1ba080c7f44@mail.gmail.com> Great : implementing __hash__ *and* operator==() did the trick ! My implementation uses this int hello::__hash__() const { //Using Duff's device version of sdbm hash func return dbm_hash(country.c_str(), country.length()); } bool hello::operator == (const hello &h) const { return __hash__() == h.__hash__(); } With the corresponding definitions for my extension class_("hello", init()) .def("__hash__", &hello::__hash__) .def(self == self) ; Thank you, -- Guillaume -------------- next part -------------- An HTML attachment was scrubbed... URL: From ndbecker2 at gmail.com Thu Mar 4 17:59:40 2010 From: ndbecker2 at gmail.com (Neal Becker) Date: Thu, 04 Mar 2010 11:59:40 -0500 Subject: [C++-sig] boost::python embedding return value Message-ID: int main () { Py_Initialize(); object main_module = import("__main__"); object main_namespace = main_module.attr("__dict__"); try { object result = exec ("import sys\n" "sys.path.append('./')\n" "import test_embed\n" "test_embed.five_square()\n", main_namespace); int five_squared = extract (result); std::cout << five_squared << '\n'; } catch (error_already_set const&) { PyErr_Print(); } } test_embed.py: -------------------- def five_square (): return 5 ** 2 I get: ./test_embed TypeError: No registered converter was able to produce a C++ rvalue of type int from this Python object of type NoneType Why did exec return None? I expected it to return the result of "test_embed.five_squared()", which is the int 25. What is the meaning of the return of exec_file? A python module can't return a result. From seefeld at sympatico.ca Thu Mar 4 18:19:18 2010 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Thu, 04 Mar 2010 12:19:18 -0500 Subject: [C++-sig] boost::python embedding return value In-Reply-To: References: Message-ID: <4B8FEB96.1060701@sympatico.ca> On 03/04/2010 11:59 AM, Neal Becker wrote: > int main () { > Py_Initialize(); > > object main_module = import("__main__"); > object main_namespace = main_module.attr("__dict__"); > > try { > object result = exec ("import sys\n" > "sys.path.append('./')\n" > "import test_embed\n" > "test_embed.five_square()\n", > main_namespace); > int five_squared = extract (result); > std::cout<< five_squared<< '\n'; > } > catch (error_already_set const&) { > PyErr_Print(); > } > } > > > test_embed.py: > -------------------- > def five_square (): > return 5 ** 2 > > I get: > ./test_embed > TypeError: No registered converter was able to produce a C++ rvalue of type > int from this Python object of type NoneType > > Why did exec return None? I expected it to return the result of > "test_embed.five_squared()", which is the int 25. What is the meaning of > the return of exec_file? A python module can't return a result. > This is a straight wrapping of Python's C API. AFAICT, the return value is only useful to determine whether the call was successful. Thus, None may indicate an internal error, which you can check for with PyErr_Occured(). (I'm actually surprised we don't catch this internally and then raise an err_already_set exception !) The real error could be that the interpreter wasn't able to import one of the modules (wrong PYTHONPATH ?), or something similar. Regards, Stefan -- ...ich hab' noch einen Koffer in Berlin... From ndbecker2 at gmail.com Thu Mar 4 19:35:44 2010 From: ndbecker2 at gmail.com (Neal Becker) Date: Thu, 04 Mar 2010 13:35:44 -0500 Subject: [C++-sig] boost::python embedding return value References: <4B8FEB96.1060701@sympatico.ca> Message-ID: Stefan Seefeld wrote: > On 03/04/2010 11:59 AM, Neal Becker wrote: >> int main () { >> Py_Initialize(); >> >> object main_module = import("__main__"); >> object main_namespace = main_module.attr("__dict__"); >> >> try { >> object result = exec ("import sys\n" >> "sys.path.append('./')\n" >> "import test_embed\n" >> "test_embed.five_square()\n", >> main_namespace); >> int five_squared = extract (result); >> std::cout<< five_squared<< '\n'; >> } >> catch (error_already_set const&) { >> PyErr_Print(); >> } >> } >> >> >> test_embed.py: >> -------------------- >> def five_square (): >> return 5 ** 2 >> >> I get: >> ./test_embed >> TypeError: No registered converter was able to produce a C++ rvalue of >> type int from this Python object of type NoneType >> >> Why did exec return None? I expected it to return the result of >> "test_embed.five_squared()", which is the int 25. What is the meaning of >> the return of exec_file? A python module can't return a result. >> > > This is a straight wrapping of Python's C API. AFAICT, the return value > is only useful to determine whether the call was successful. Thus, None > may indicate an internal error, which you can check for with > PyErr_Occured(). (I'm actually surprised we don't catch this internally > and then raise an err_already_set exception !) > > The real error could be that the interpreter wasn't able to import one > of the modules (wrong PYTHONPATH ?), or something similar. > > Regards, > Stefan > That's strange, because docs for exec and exec_file claim to return object. From seefeld at sympatico.ca Thu Mar 4 19:49:10 2010 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Thu, 04 Mar 2010 13:49:10 -0500 Subject: [C++-sig] boost::python embedding return value In-Reply-To: References: <4B8FEB96.1060701@sympatico.ca> Message-ID: <4B9000A6.5050105@sympatico.ca> Neal, I should have read your mail more carefully before replying. Sorry for that. On 03/04/2010 01:35 PM, Neal Becker wrote: > Stefan Seefeld wrote: > > >> On 03/04/2010 11:59 AM, Neal Becker wrote: >> >>> int main () { >>> Py_Initialize(); >>> >>> object main_module = import("__main__"); >>> object main_namespace = main_module.attr("__dict__"); >>> >>> try { >>> object result = exec ("import sys\n" >>> "sys.path.append('./')\n" >>> "import test_embed\n" >>> "test_embed.five_square()\n", >>> main_namespace); >>> int five_squared = extract (result); >>> std::cout<< five_squared<< '\n'; >>> } >>> catch (error_already_set const&) { >>> PyErr_Print(); >>> } >>> } >>> >>> >>> test_embed.py: >>> -------------------- >>> def five_square (): >>> return 5 ** 2 >>> >>> I get: >>> ./test_embed >>> TypeError: No registered converter was able to produce a C++ rvalue of >>> type int from this Python object of type NoneType >>> The problem is that you shouldn't attempt to extract anything from the return value of an exec() call. It will contain None if everything goes well. If not, the C API returns a null-pointer, which boost.python translates into an err_already_set exception. I'm not exactly sure what you attempt to do. If you really want to evaluate an expression (inclusively a function call), you should use eval(), instead of exec(). The typical usage of exec() will be to run some code, then inspect the global namespace to inspect any "side-effects" of this execution. Notably, you may have your Python module store objects in the namespace, and then let your C++ code extract and use them. For example std::string code = "import test_embed\n" "result = test_embed.five_square()"; object = exec(code, global, global); int result = extract(global["result"]); Hope this helps, Stefan -- ...ich hab' noch einen Koffer in Berlin... From ndbecker2 at gmail.com Thu Mar 4 19:59:45 2010 From: ndbecker2 at gmail.com (Neal Becker) Date: Thu, 04 Mar 2010 13:59:45 -0500 Subject: [C++-sig] boost::python embedding return value References: <4B8FEB96.1060701@sympatico.ca> <4B9000A6.5050105@sympatico.ca> Message-ID: Stefan Seefeld wrote: > Neal, > > I should have read your mail more carefully before replying. Sorry for > that. > > > On 03/04/2010 01:35 PM, Neal Becker wrote: >> Stefan Seefeld wrote: >> >> >>> On 03/04/2010 11:59 AM, Neal Becker wrote: >>> >>>> int main () { >>>> Py_Initialize(); >>>> >>>> object main_module = import("__main__"); >>>> object main_namespace = main_module.attr("__dict__"); >>>> >>>> try { >>>> object result = exec ("import sys\n" >>>> "sys.path.append('./')\n" >>>> "import test_embed\n" >>>> "test_embed.five_square()\n", >>>> main_namespace); >>>> int five_squared = extract (result); >>>> std::cout<< five_squared<< '\n'; >>>> } >>>> catch (error_already_set const&) { >>>> PyErr_Print(); >>>> } >>>> } >>>> >>>> >>>> test_embed.py: >>>> -------------------- >>>> def five_square (): >>>> return 5 ** 2 >>>> >>>> I get: >>>> ./test_embed >>>> TypeError: No registered converter was able to produce a C++ rvalue of >>>> type int from this Python object of type NoneType >>>> > > The problem is that you shouldn't attempt to extract anything from the > return value of an exec() call. It will contain None if everything goes > well. If not, the C API returns a null-pointer, which boost.python > translates into an err_already_set exception. > > I'm not exactly sure what you attempt to do. If you really want to > evaluate an expression (inclusively a function call), you should use > eval(), instead of exec(). > > The typical usage of exec() will be to run some code, then inspect the > global namespace to inspect any "side-effects" of this execution. > Notably, you may have your Python module store objects in the namespace, > and then let your C++ code extract and use them. > For example > > std::string code = > "import test_embed\n" > "result = test_embed.five_square()"; > > object = exec(code, global, global); > int result = extract(global["result"]); > > Hope this helps, > Stefan > OK. I had assumed, since it returned an object, that I could call a function and get back the python result. I didn't use eval, because eval is restricted to 1 expression, and so couldn't do something like: ''' sys.path.append('./') import module module.F (3)''' which is what I was trying to do From seefeld at sympatico.ca Thu Mar 4 20:08:20 2010 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Thu, 04 Mar 2010 14:08:20 -0500 Subject: [C++-sig] boost::python embedding return value In-Reply-To: References: <4B8FEB96.1060701@sympatico.ca> <4B9000A6.5050105@sympatico.ca> Message-ID: <4B900524.4000003@sympatico.ca> On 03/04/2010 01:59 PM, Neal Becker wrote: > > OK. I had assumed, since it returned an object, that I could call a > function and get back the python result. I didn't use eval, because eval is > restricted to 1 expression, and so couldn't do something like: > ''' > sys.path.append('./') > import module > module.F (3)''' > > which is what I was trying to do > OK. If you want to do this once, this seems a good approach. However, for doing it repeatedly it might be better to first execute the "startup" code, such that "module" ends up in a dictionary ("global", in my case). Then you can run eval() on the expression you'd like to get the result of: exec(code, global); for(...) { int result = extract(eval("module.F(3)", global)); ... } Thus you only need to execute common startup code once. Stefan -- ...ich hab' noch einen Koffer in Berlin... From charlessolar at gmail.com Sun Mar 7 07:23:12 2010 From: charlessolar at gmail.com (Charles Solar) Date: Sun, 7 Mar 2010 00:23:12 -0600 Subject: [C++-sig] Virtual methods with arguments and boost::cref Message-ID: <708326ee1003062223v1be26444k13f49544103e0331@mail.gmail.com> I have some virtual methods with default implementations that I am defining according the guidelines on the documentation and I ran into some unexpected behavior. If I define a virtual method in boost python like so void receivedMsg( const sl::Message& msg ) { if( bp::override func_receivedMsg = this->get_override( "receivedMsg" ) ) func_receivedMsg( boost::cref( msg ) ); } it works fine, my receivedMsg function gets called in python no problem. Note that I am not calling the default implementation because the default implementation does not do anything, I do not want to make them pure virtual because the idea is that the user only has to define the methods he wants notifications on. My trouble comes when I do void receiverDeleted( const std::string& type, const std::string& name ) { if( bp::override func_receiverDeleted = this->get_override( "receiverDeleted" ) ) func_receiverDeleted( boost::cref( type ), boost::cref( name ) ); } I get a error_already_set exception because the mechanics under the hood cannot pythonize the boost::cref( type ). In my first example, Message is defined in python so I guess cref works like that, but the default converter for std::string must not like the boost::cref wrapper. I do not get the exception and it seems to work fine if I remove the crefs. I added the cref's a while ago because it seemed like the right thing to do. I do not want boost::python creating copies of my objects under the hood, maybe it does anyway, I do not know. Do the crefs do anything? Should I even have them? Is this a bug or just me being stupid? :p Thanks -------------- next part -------------- An HTML attachment was scrubbed... URL: From p.schellart at gmail.com Mon Mar 8 13:32:22 2010 From: p.schellart at gmail.com (Pim Schellart) Date: Mon, 8 Mar 2010 13:32:22 +0100 Subject: [C++-sig] Status of Numpy support in boost python Message-ID: <7d3dada91003080432gc0e49cta240e4c4b5ab7d05@mail.gmail.com> Hello Everyone, we are working on a project for which it would be extremely useful if numpy arrays could be passed as arguments to wrapped C++ methods. On the website I cannot find any evidence that this is currently supported by Boost Python. Is this (or will this be) implemented? Kind regards, Pim Schellart From seefeld at sympatico.ca Mon Mar 8 14:08:31 2010 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Mon, 08 Mar 2010 08:08:31 -0500 Subject: [C++-sig] Status of Numpy support in boost python In-Reply-To: <7d3dada91003080432gc0e49cta240e4c4b5ab7d05@mail.gmail.com> References: <7d3dada91003080432gc0e49cta240e4c4b5ab7d05@mail.gmail.com> Message-ID: <4B94F6CF.6000504@sympatico.ca> On 03/08/2010 07:32 AM, Pim Schellart wrote: > Hello Everyone, > > we are working on a project for which it would be extremely useful if > numpy arrays could be passed as arguments to wrapped C++ methods. > On the website I cannot find any evidence that this is currently > supported by Boost Python. > Is this (or will this be) implemented? > At present, boost.python provides an 'array' type that corresponds to Python's numpy.ndarray. However, the wrapper isn't rich enough for example to pass raw data pointers, making it not suitable for some applications. Docs for the existing facilities can be found at http://www.boost.org/doc/libs/1_41_0/libs/python/doc/v2/numeric.html. We have had a couple of discussions about improving boost.python's support for numpy, but nothing materialized yet. May be we should rally up enough momentum to get this done. Thanks, Stefan -- ...ich hab' noch einen Koffer in Berlin... From talljimbo at gmail.com Mon Mar 8 19:20:03 2010 From: talljimbo at gmail.com (Jim Bosch) Date: Mon, 08 Mar 2010 10:20:03 -0800 Subject: [C++-sig] Status of Numpy support in boost python In-Reply-To: <4B94F6CF.6000504@sympatico.ca> References: <7d3dada91003080432gc0e49cta240e4c4b5ab7d05@mail.gmail.com> <4B94F6CF.6000504@sympatico.ca> Message-ID: <1268072403.2810.8.camel@mu> On Mon, 2010-03-08 at 08:08 -0500, Stefan Seefeld wrote: > On 03/08/2010 07:32 AM, Pim Schellart wrote: > > Hello Everyone, > > > > we are working on a project for which it would be extremely useful if > > numpy arrays could be passed as arguments to wrapped C++ methods. > > On the website I cannot find any evidence that this is currently > > supported by Boost Python. > > Is this (or will this be) implemented? > > > > At present, boost.python provides an 'array' type that corresponds to > Python's numpy.ndarray. > However, the wrapper isn't rich enough for example to pass raw data > pointers, making it not suitable for some applications. > > Docs for the existing facilities can be found at > http://www.boost.org/doc/libs/1_41_0/libs/python/doc/v2/numeric.html. > > We have had a couple of discussions about improving boost.python's > support for numpy, but nothing materialized yet. May be we should rally > up enough momentum to get this done. > > I have fairly complete library along these lines that I have been slowly cleaning up for public release, and I could probably submit a fairly complete proposal over the next few weeks if there is interest. It's met my needs quite well over the past few years, but I think it would benefit from input from the community. Is there someplace standard for hosting/publishing extensions to boost.python that I should be aware of? What I would consider a compute Numpy interface is probably not something that should be added into the main boost.python library itself (and I think it would need it's own shared library if done properly). Jim Bosch From seefeld at sympatico.ca Mon Mar 8 19:29:01 2010 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Mon, 08 Mar 2010 13:29:01 -0500 Subject: [C++-sig] Status of Numpy support in boost python In-Reply-To: <1268072403.2810.8.camel@mu> References: <7d3dada91003080432gc0e49cta240e4c4b5ab7d05@mail.gmail.com> <4B94F6CF.6000504@sympatico.ca> <1268072403.2810.8.camel@mu> Message-ID: <4B9541ED.1050805@sympatico.ca> On 03/08/2010 01:20 PM, Jim Bosch wrote: > > I have fairly complete library along these lines that I have been slowly > cleaning up for public release, and I could probably submit a fairly > complete proposal over the next few weeks if there is interest. It's > met my needs quite well over the past few years, but I think it would > benefit from input from the community. > > Is there someplace standard for hosting/publishing extensions to > boost.python that I should be aware of? What I would consider a compute > Numpy interface is probably not something that should be added into the > main boost.python library itself (and I think it would need it's own > shared library if done properly). > Oh, interesting. I have written a PyArray wrapper myself, and it is only a single header right now. For a full library I would certainly suggest the sandbox. There we may discuss, and then merge into trunk as we see fits. (I'd suggest boost/sandbox/numpy for this.) Thanks, Stefan -- ...ich hab' noch einen Koffer in Berlin... From ndbecker2 at gmail.com Mon Mar 8 19:30:13 2010 From: ndbecker2 at gmail.com (Neal Becker) Date: Mon, 08 Mar 2010 13:30:13 -0500 Subject: [C++-sig] Status of Numpy support in boost python References: <7d3dada91003080432gc0e49cta240e4c4b5ab7d05@mail.gmail.com> <4B94F6CF.6000504@sympatico.ca> <1268072403.2810.8.camel@mu> Message-ID: >Jim Bosch wrote: > On Mon, 2010-03-08 at 08:08 -0500, Stefan Seefeld wrote: >> On 03/08/2010 07:32 AM, Pim Schellart wrote: >> > Hello Everyone, >> > >> > we are working on a project for which it would be extremely useful if >> > numpy arrays could be passed as arguments to wrapped C++ methods. >> > On the website I cannot find any evidence that this is currently >> > supported by Boost Python. >> > Is this (or will this be) implemented? >> > >> >> At present, boost.python provides an 'array' type that corresponds to >> Python's numpy.ndarray. >> However, the wrapper isn't rich enough for example to pass raw data >> pointers, making it not suitable for some applications. >> >> Docs for the existing facilities can be found at >> http://www.boost.org/doc/libs/1_41_0/libs/python/doc/v2/numeric.html. >> >> We have had a couple of discussions about improving boost.python's >> support for numpy, but nothing materialized yet. May be we should rally >> up enough momentum to get this done. >> >> > > I have fairly complete library along these lines that I have been slowly > cleaning up for public release, and I could probably submit a fairly > complete proposal over the next few weeks if there is interest. It's > met my needs quite well over the past few years, but I think it would > benefit from input from the community. > > Is there someplace standard for hosting/publishing extensions to > boost.python that I should be aware of? What I would consider a compute > Numpy interface is probably not something that should be added into the > main boost.python library itself (and I think it would need it's own > shared library if done properly). > > Jim Bosch Check out pyublas From seefeld at sympatico.ca Mon Mar 8 19:40:02 2010 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Mon, 08 Mar 2010 13:40:02 -0500 Subject: [C++-sig] Status of Numpy support in boost python In-Reply-To: References: <7d3dada91003080432gc0e49cta240e4c4b5ab7d05@mail.gmail.com> <4B94F6CF.6000504@sympatico.ca> <1268072403.2810.8.camel@mu> Message-ID: <4B954482.6010201@sympatico.ca> On 03/08/2010 01:30 PM, Neal Becker wrote: > > Check out pyublas > Thanks for mentioning that. Yes, this looks very useful. In fact, my PyArray wrapper was inspired by pyublas. I think it would be useful to integrate the PyArray wrapper right into boost.python. Other libraries which provide more functionality (such as pyublas, or the one Jim is talking about) can then use that wrapper, instead of having to provide it themselves. This should notably also improve interoperability, since the boost.python type registry doesn't (yet) allow multiple wrappers for the same types. Stefan -- ...ich hab' noch einen Koffer in Berlin... From talljimbo at gmail.com Mon Mar 8 20:11:47 2010 From: talljimbo at gmail.com (Jim Bosch) Date: Mon, 08 Mar 2010 11:11:47 -0800 Subject: [C++-sig] Status of Numpy support in boost python In-Reply-To: <4B954482.6010201@sympatico.ca> References: <7d3dada91003080432gc0e49cta240e4c4b5ab7d05@mail.gmail.com> <4B94F6CF.6000504@sympatico.ca> <1268072403.2810.8.camel@mu> <4B954482.6010201@sympatico.ca> Message-ID: <1268075507.3164.21.camel@mu> On Mon, 2010-03-08 at 13:40 -0500, Stefan Seefeld wrote: > On 03/08/2010 01:30 PM, Neal Becker wrote: > > > > Check out pyublas > > > > Thanks for mentioning that. > > Yes, this looks very useful. In fact, my PyArray wrapper was inspired by > pyublas. Definitely useful, and from what I've seen from a quick glance, a very nice API. I'm personally using Eigen2 rather than boost.ublas - do you have any comment on whether this could be made more generic so as to support other C++ matrix libraries? Of course, ublas is in boost, so it's clearly the most important target. > I think it would be useful to integrate the PyArray wrapper right into > boost.python. > I generally agree, but I dislike the idea of including the numpy C-API header file in all its preprocessor-macro glory in a file which will be included by users, and I've found it hard to avoid that in a header-only library. What was your solution? > Other libraries which provide more functionality (such as pyublas, or > the one Jim is talking about) can then use that wrapper, instead of > having to provide it themselves. This should notably also improve > interoperability, since the boost.python type registry doesn't (yet) > allow multiple wrappers for the same types. This does seem like the best way to go, if we can find a solution to the numpy header problem that doesn't require building the boost.python library itself against numpy. By the way, here's what I've got - it seems to complement pyublas pretty well: - A few "object manager" types for numpy.ndarray, numpy.dtype, numpy.matrix, and numpy.void scalars, and a pretty easy system for adding more. These present a boost.python interface to the parts of the Numpy C-API, and it sounds like they're pretty similar in spirit to your PyArray. I'll look into putting them into the sandbox. - A tool for creating broadcasting python callables from arbitrary C++ objects that overload operator(). - A multidimensional array template library patterned after numpy; this is definitely not something that belongs in boost.python, but I find that they work very well together: http://code.google.com/p/ndarray/ It would really great if boost.multiarray could fill such a role, but I found it doesn't do everything needed in talking to numpy - particularly the ability to handle shared data. Jim From seefeld at sympatico.ca Mon Mar 8 20:38:11 2010 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Mon, 08 Mar 2010 14:38:11 -0500 Subject: [C++-sig] Status of Numpy support in boost python In-Reply-To: <1268075507.3164.21.camel@mu> References: <7d3dada91003080432gc0e49cta240e4c4b5ab7d05@mail.gmail.com> <4B94F6CF.6000504@sympatico.ca> <1268072403.2810.8.camel@mu> <4B954482.6010201@sympatico.ca> <1268075507.3164.21.camel@mu> Message-ID: <4B955223.3090207@sympatico.ca> On 03/08/2010 02:11 PM, Jim Bosch wrote: > >> I think it would be useful to integrate the PyArray wrapper right into >> boost.python. >> >> > I generally agree, but I dislike the idea of including the numpy C-API > header file in all its preprocessor-macro glory in a file which will be > included by users, and I've found it hard to avoid that in a header-only > library. What was your solution? > In my setup I check for the python-numpy package (on Fedora), which provides the numpy/arrayobject.h header (assuming this is the one you mean). However, I'm not sure I understand your concern. Boost.python isn't a header-only library, so it may well hide the above header by compiling it into its own object file. To me, the most important feature in adding proper PyArray support to boost.python is the ability to access the much richer API, such as direct-data access via PyArr_DATA, PyArr_GETPTRX, etc., which allow me to build my own adapter, so different parts of a hybrid application can pass arrays around without the need to copy. >> Other libraries which provide more functionality (such as pyublas, or >> the one Jim is talking about) can then use that wrapper, instead of >> having to provide it themselves. This should notably also improve >> interoperability, since the boost.python type registry doesn't (yet) >> allow multiple wrappers for the same types. >> > This does seem like the best way to go, if we can find a solution to the > numpy header problem that doesn't require building the boost.python > library itself against numpy. > Hmm, this is a good point: By compiling the numpy wrapper as part of boost.python, we would make numpy a prerequisite for boost.python, which isn't a good idea. So keeping it header-only may be better. I'm still not sure what your concern is with the numpy header. Why can't it be exposed to user code ? May be you can indeed make a case for a compiled boost.numpy library... > By the way, here's what I've got - it seems to complement pyublas pretty > well: > > > - A few "object manager" types for numpy.ndarray, numpy.dtype, > numpy.matrix, and numpy.void scalars, and a pretty easy system for > adding more. These present a boost.python interface to the parts of the > Numpy C-API, and it sounds like they're pretty similar in spirit to your > PyArray. I'll look into putting them into the sandbox. > That looks good. Thanks ! > - A tool for creating broadcasting python callables from arbitrary C++ > objects that overload operator(). > Would this be a generator for ufuncs ? > - A multidimensional array template library patterned after numpy; this > is definitely not something that belongs in boost.python, but I find > that they work very well together: > > http://code.google.com/p/ndarray/ > Ah. That sounds useful, but I agree, not like something that belongs into a generic numpy wrapper library. > It would really great if boost.multiarray could fill such a role, but I > found it doesn't do everything needed in talking to numpy - particularly > the ability to handle shared data. > Thanks. I'd very much like to see a discussion of how to move the above numpy wrapper into boost.python (possibly as a new compiled boost.numpy library). Thanks, Stefan -- ...ich hab' noch einen Koffer in Berlin... From talljimbo at gmail.com Mon Mar 8 22:57:31 2010 From: talljimbo at gmail.com (Jim Bosch) Date: Mon, 08 Mar 2010 13:57:31 -0800 Subject: [C++-sig] Status of Numpy support in boost python In-Reply-To: <4B955223.3090207@sympatico.ca> References: <7d3dada91003080432gc0e49cta240e4c4b5ab7d05@mail.gmail.com> <4B94F6CF.6000504@sympatico.ca> <1268072403.2810.8.camel@mu> <4B954482.6010201@sympatico.ca> <1268075507.3164.21.camel@mu> <4B955223.3090207@sympatico.ca> Message-ID: <1268085451.5116.7.camel@mu> On Mon, 2010-03-08 at 14:38 -0500, Stefan Seefeld wrote: > To me, the most important feature in adding proper PyArray support to > boost.python is the ability to access the much richer API, such as > direct-data access via PyArr_DATA, PyArr_GETPTRX, etc., which allow me > to build my own adapter, so different parts of a hybrid application can > pass arrays around without the need to copy. > I agree. The whole point of using numpy with C++ is to be able to go from raw pointers to numpy arrays and back, and that doesn't seem to be possible with an interface that just calls the Python API (as the numeric interface does at present). > > Hmm, this is a good point: By compiling the numpy wrapper as part of > boost.python, we would make numpy a prerequisite for boost.python, which > isn't a good idea. So keeping it header-only may be better. > I'm still not sure what your concern is with the numpy header. Why can't > it be exposed to user code ? > I just don't like that you have to #define something before including the header, and that it's different in the source file that calls "import_array()" than in all the others. In fact, I find it unfortunate that "import_array()" needs to be called at all, but I haven't found a way around that. I'm also mildly annoyed that it doesn't #include even though it requires it. This is all just a really ugly replacement for namespaces, and it may be necessary in C extensions, but shouldn't be necessary in a C++ extension. You should be able to just do "#include > > - A tool for creating broadcasting python callables from arbitrary C++ > > objects that overload operator(). > > > > Would this be a generator for ufuncs ? > Not in any technical sense of the word "generator", I think, and it doesn't actually use the numpy.ufunc type (because that requires a true function pointer), but that's essentially the idea. Finally, I've checked in what I have so far in the sandbox: http://svn.boost.org/svn/boost/sandbox/numpy/ There's still a lot to do before I'd call it complete, but it has (IMO) the most important low-level functionality. If anyone wants to toss in a bjam-based build system, I'd much appreciate it - I don't know jam at all. Jim From seefeld at sympatico.ca Mon Mar 8 23:04:34 2010 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Mon, 08 Mar 2010 17:04:34 -0500 Subject: [C++-sig] Status of Numpy support in boost python In-Reply-To: <1268085451.5116.7.camel@mu> References: <7d3dada91003080432gc0e49cta240e4c4b5ab7d05@mail.gmail.com> <4B94F6CF.6000504@sympatico.ca> <1268072403.2810.8.camel@mu> <4B954482.6010201@sympatico.ca> <1268075507.3164.21.camel@mu> <4B955223.3090207@sympatico.ca> <1268085451.5116.7.camel@mu> Message-ID: <4B957472.4000707@sympatico.ca> On 03/08/2010 04:57 PM, Jim Bosch wrote: > >> Hmm, this is a good point: By compiling the numpy wrapper as part of >> boost.python, we would make numpy a prerequisite for boost.python, which >> isn't a good idea. So keeping it header-only may be better. >> I'm still not sure what your concern is with the numpy header. Why can't >> it be exposed to user code ? >> >> > I just don't like that you have to #define something before including > the header, and that it's different in the source file that calls > "import_array()" than in all the others. In fact, I find it unfortunate > that "import_array()" needs to be called at all, but I haven't found a > way around that. I'm also mildly annoyed that it doesn't #include > even though it requires it. > > This is all just a really ugly replacement for namespaces, and it may be > necessary in C extensions, but shouldn't be necessary in a C++ > extension. You should be able to just do > "#include (or whatever) and have it all just work. > Right. And that's all the users of my wrapper do. Everything else happens within my wrapper code. > Finally, I've checked in what I have so far in the sandbox: > > http://svn.boost.org/svn/boost/sandbox/numpy/ > Thanks, I'll have a look. > There's still a lot to do before I'd call it complete, but it has (IMO) > the most important low-level functionality. If anyone wants to toss in > a bjam-based build system, I'd much appreciate it - I don't know jam at > all. > I'm little better, but will try to clone something I know works. Ping me in a couple of days, if you haven't heard back from me. Thanks, Stefan -- ...ich hab' noch einen Koffer in Berlin... From dr.cg at 126.com Tue Mar 9 07:45:30 2010 From: dr.cg at 126.com (CHEN Guang) Date: Tue, 9 Mar 2010 14:45:30 +0800 (CST) Subject: [C++-sig] The C language for Python programmers --- PythoidC Message-ID: Hi, if you want to write and run C code in Python IDE with auto-completion if you want to introspect into C functions and data structs if you hate the {} and ; and the DOS window (console) Please take a look at: http://pythoidc.googlecode.com PythoidC is the C language like the Python, by the Python and for the Python import c c.include(c.h.stdio) c.include(c.h.stdlib) '''Annotation is free!''' int fib(int n): if(n<=2): return1 else: return fib(n-1)+ fib(n-2) int main(int argc,char**argv): int n //C style annotation n=c.stdlib.atoi(argv[1]) c.stdio.printf('fibonacci(%d)=%d\n', n, fib(n)) -------------- next part -------------- An HTML attachment was scrubbed... URL: From p.schellart at gmail.com Tue Mar 9 12:34:00 2010 From: p.schellart at gmail.com (Pim Schellart) Date: Tue, 9 Mar 2010 12:34:00 +0100 Subject: [C++-sig] Status of Numpy support in boost python Message-ID: <7d3dada91003090334o34ebf9dfj11023986a081406a@mail.gmail.com> Hi Everyone, wow! I am overwhelmed by the amount of response to this request. I looked at the other options and must say I agree with Jim Bosch' comment: > The whole point of using numpy with C++ is to be able to go > from raw pointers to numpy arrays and back, and that doesn't seem to be > possible with an interface that just calls the Python API (as the > numeric interface does at present). for fast numerical calculations callbacks into Python are not a good option. In terms of the discussion concerning compiled or header only I think that although it would be nice and clean to have a header only library, as it stands boost python has to be compiled anyway and I think adding numpy as an optional dependency would not be bad because users who want to use this functionality by definition have numpy installed as well. I do think it would not be good to add it as a required dependency for boost python since numpy is (not yet) part of the Python standard library. Since I am not a core numpy or boost developer and have little experience working directly with the numpy C api any code contributions from me would probably be ugly. However I am keen to see numpy support in boost python as soon as possible and would like to help on for instance testing or writing documentation. I could probably also help to add the numpy support to the cmake builld system for boost. Kind regards, Pim Schellart From seefeld at sympatico.ca Tue Mar 9 12:59:25 2010 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Tue, 09 Mar 2010 06:59:25 -0500 Subject: [C++-sig] Status of Numpy support in boost python In-Reply-To: <7d3dada91003090334o34ebf9dfj11023986a081406a@mail.gmail.com> References: <7d3dada91003090334o34ebf9dfj11023986a081406a@mail.gmail.com> Message-ID: <4B96381D.5040206@sympatico.ca> On 03/09/2010 06:34 AM, Pim Schellart wrote: > > for fast numerical calculations callbacks into Python are not a good option. > In terms of the discussion concerning compiled or header only I think > that although it would be nice and clean to have a header only > library, as it stands boost python has to be compiled anyway and I > think adding numpy as an optional dependency would not be bad because > users who want to use this functionality by definition have numpy > installed as well. > You may be forgetting that the one installing boost.python isn't necessarily the one compiling it. Not all users of boost.python need numpy. Thus, should there be two boost.python packages, one with and one without numpy dependency ? I think it would be cleaner to factor that out, unless it can be kept in a header-only form. Stefan -- ...ich hab' noch einen Koffer in Berlin... From ndbecker2 at gmail.com Tue Mar 9 17:53:05 2010 From: ndbecker2 at gmail.com (Neal Becker) Date: Tue, 09 Mar 2010 11:53:05 -0500 Subject: [C++-sig] Status of Numpy support in boost python References: <7d3dada91003080432gc0e49cta240e4c4b5ab7d05@mail.gmail.com> <4B94F6CF.6000504@sympatico.ca> <1268072403.2810.8.camel@mu> <4B954482.6010201@sympatico.ca> <1268075507.3164.21.camel@mu> Message-ID: No luck with boost-1.42. fedora-12 boost-1.39 seems OK. Lots of errors, like: /usr/local/src/boost.hg/boost/fusion/container/vector/convert.hpp: In instantiation of 'boost::fusion::result_of::as_vector, 0>, boost::fusion::vector_iterator, -0x00000000000000001> > >': include/ndarray/views.hpp:210: instantiated from 'ndarray::detail::ViewTraits<3, 3, boost::fusion::vector0 >' include/ndarray/views.hpp:216: instantiated from 'ndarray::detail::ViewTraits<3, 3, boost::fusion::vector1 >' include/ndarray/views.hpp:216: instantiated from 'ndarray::detail::ViewTraits<3, 3, boost::fusion::vector2 >' include/ndarray/views.hpp:216: instantiated from 'ndarray::detail::ViewTraits<3, 3, boost::fusion::vector3 >' include/ndarray/Array.hpp:136: instantiated from 'ndarray::Array::ResultOf >, boost::fusion::vector3 >' tests/ndarray.cc:109: instantiated from here /usr/local/src/boost.hg/boost/fusion/container/vector/convert.hpp:26: error: invalid use of incomplete type 'struct boost::fusion::detail::as_vector<-0x00000000000000001>' /usr/local/src/boost.hg/boost/fusion/container/vector/detail/as_vector.hpp:26: error: declaration of 'struct boost::fusion::detail::as_vector<-0x00000000000000001>' tests/ndarray.cc: In member function 'void casts::test_method()': tests/ndarray.cc:109: error: no match for 'operator[]' in 'd[ndarray::View::operator()() const [with SeqT = boost::fusion::vector2] ()]' From ndbecker2 at gmail.com Tue Mar 9 01:41:18 2010 From: ndbecker2 at gmail.com (Neal Becker) Date: Mon, 08 Mar 2010 19:41:18 -0500 Subject: [C++-sig] Status of Numpy support in boost python References: <7d3dada91003080432gc0e49cta240e4c4b5ab7d05@mail.gmail.com> <4B94F6CF.6000504@sympatico.ca> <1268072403.2810.8.camel@mu> <4B954482.6010201@sympatico.ca> <1268075507.3164.21.camel@mu> <4B955223.3090207@sympatico.ca> <1268085451.5116.7.camel@mu> <4B957472.4000707@sympatico.ca> Message-ID: Do you intend to include some examples? From seefeld at sympatico.ca Tue Mar 9 19:12:12 2010 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Tue, 09 Mar 2010 13:12:12 -0500 Subject: [C++-sig] Status of Numpy support in boost python In-Reply-To: References: <7d3dada91003080432gc0e49cta240e4c4b5ab7d05@mail.gmail.com> <4B94F6CF.6000504@sympatico.ca> <1268072403.2810.8.camel@mu> <4B954482.6010201@sympatico.ca> <1268075507.3164.21.camel@mu> <4B955223.3090207@sympatico.ca> <1268085451.5116.7.camel@mu> <4B957472.4000707@sympatico.ca> Message-ID: <4B968F7C.1070108@sympatico.ca> On 03/08/2010 07:41 PM, Neal Becker wrote: > Do you intend to include some examples? > That is unfortunately not quite easy, as the (in this context) interesting bits are mixed with lots of other code that is not relevant here. I will try to refactor things the way I envision this array wrapper to look like. Thanks, Stefan -- ...ich hab' noch einen Koffer in Berlin... From talljimbo at gmail.com Tue Mar 9 19:35:45 2010 From: talljimbo at gmail.com (Jim Bosch) Date: Tue, 09 Mar 2010 10:35:45 -0800 Subject: [C++-sig] Status of Numpy support in boost python In-Reply-To: References: <7d3dada91003080432gc0e49cta240e4c4b5ab7d05@mail.gmail.com> <4B94F6CF.6000504@sympatico.ca> <1268072403.2810.8.camel@mu> <4B954482.6010201@sympatico.ca> <1268075507.3164.21.camel@mu> Message-ID: <1268159745.8590.10.camel@mu> On Tue, 2010-03-09 at 11:53 -0500, Neal Becker wrote: > No luck with boost-1.42. fedora-12 boost-1.39 seems OK. > > Lots of errors, like: > /usr/local/src/boost.hg/boost/fusion/container/vector/convert.hpp: In > instantiation of > 'boost::fusion::result_of::as_vector, > 0>, boost::fusion::vector_iterator, > -0x00000000000000001> > >': > tests/ndarray.cc: In member function 'void casts::test_method()': > tests/ndarray.cc:109: error: no match for 'operator[]' in > 'd[ndarray::View::operator()() const [with SeqT = > boost::fusion::vector2] > ()]' > Just to keep everyone following this thread sane, I'd like to point out that this refers to my ndarray C++ library, *not* what I put in the boost sandbox; the latter is much simpler, much more boost.python-specific, and generally lower-level. I'd like it to morph into something that could be included as an optional part of boost.python, and I'd ultimately like to rewrite the Python-interfacing parts of my ndarray library to make use of it. That said, thanks for the heads-up on the compile failures in ndarray, Neil - I've been using boost 1.40, and it looks like I've got some work to do to make it compatible with later releases. I'll keep the list posted on my progress, and I'll look into making some examples as well. Jim From guillaume at paralint.com Thu Mar 11 22:48:20 2010 From: guillaume at paralint.com (Guillaume Seguin) Date: Thu, 11 Mar 2010 16:48:20 -0500 Subject: [C++-sig] Virtual functions : should I use wrapper::get_override or call_method and boost::ref ? Message-ID: <42d7ad4f1003111348t6ec288bmbca39af5b965a06f@mail.gmail.com> Boost.Python 1.42 documentation shows how to overload virtual functions using boost::python::wrapper::get_override. I made the example work. Now I am struggling with a inheritance problem with virtual functions calling each other, with a mix and match of Python and C++ implementation of a common base. I saw that in the distribution's "test" directory, as well as in the paper "Building Hybrid System with Boost.Python", call_method and boost::ref are used instead of wrapper::get_override. What is the difference between the two approach ? Given a class hierarchy like the one below, wich road should I take ? //Simplified C++ version struct Base { virtual int f() = 0; virtual void call_f(Base &b) { this->f(); b.f(); } /* this pointer will always be specialized */ } struct BaseWrap : Base, /*should I inherit from wrapper here... */ { int f() { /* or use call_method here ??? */ } struct Derived1 : Base /* or BaseWrap ? */ { int f() { return 1; } } struct Derived2 : Base /* or BaseWrap ? */ { int f() { return 2; } } #Extended in Pyhton class PyDerived1(Derived1): def f(self): return -Derived1.f(self); #Calling the ancestor class is a requirement class PyDerived2(Derived2): def f(self): return -Derived2.f(self); #Calling the ancestor class is a requirement #And called like this py1 = PyDerived1() py2 = PyDerived2() py1.call_f(py2) TIA, -- Guillaume -------------- next part -------------- An HTML attachment was scrubbed... URL: From hitesh.dhiman.1988 at gmail.com Fri Mar 12 03:36:34 2010 From: hitesh.dhiman.1988 at gmail.com (hitesh dhiman) Date: Fri, 12 Mar 2010 10:36:34 +0800 Subject: [C++-sig] boost.python class constructor error Message-ID: This error occurs when i declare the class constructor in the c++ header file and the definition in the .cpp file. Bjam throws up a LNK2019 error, unresolved symbol. But if i declare the class constructor in the header file itself, the code compiles. Here's the code: *Test1.h* #include //using namespace std; class World { public: World(); ~World(); void set(std::string msg) { this->msg = msg; } std::string greet() { return msg; } std::string msg; }; *Test1.cpp* #include "Test1.h" World::World() {}; World::~World() {}; int addition(int a, int b) { int z = a + b; return z; } *Wrapper file:* * #include #include "Test1.h" BOOST_PYTHON_MODULE(hello) { using namespace boost::python; class_("World") .def("greet", &World::greet) .def("set", &World::set) ; } Is it a compiler bug? I want to define the constructors in the cpp file, and not the header file. * -- Regards, Hitesh -------------- next part -------------- An HTML attachment was scrubbed... URL: From talljimbo at gmail.com Fri Mar 12 04:38:52 2010 From: talljimbo at gmail.com (Jim Bosch) Date: Thu, 11 Mar 2010 19:38:52 -0800 Subject: [C++-sig] boost.python class constructor error In-Reply-To: References: Message-ID: <1268365132.1706.3.camel@mu> On Fri, 2010-03-12 at 10:36 +0800, hitesh dhiman wrote: > This error occurs when i declare the class constructor in the c++ > header file and the definition in the .cpp file. Bjam throws up a > LNK2019 error, unresolved symbol. > But if i declare the class constructor in the header file itself, the > code compiles. > Here's the code: > > > Test1.h > #include > //using namespace std; > > > class World > { > public: > World(); > ~World(); > void set(std::string msg) { this->msg = msg; } > std::string greet() { return msg; } > std::string msg; > }; > > > Test1.cpp > #include "Test1.h" > > > > > World::World() {}; > World::~World() {}; > int addition(int a, int b) > { > int z = a + b; > return z; > } > > > Wrapper file: > #include > #include "Test1.h" > > > > > BOOST_PYTHON_MODULE(hello) > { > using namespace boost::python; > class_("World") > > .def("greet", &World::greet) > .def("set", &World::set) > ; > } > > > Is it a compiler bug? I want to define the constructors in the cpp > file, and not the header file. > -- I've never had any problems doing exactly that, and I can't say more about your particular situation without seeing your build system setup (which probably actually wouldn't help me, since I don't know much about bjam or Windows). Are you certain your source file is getting compiled into (or otherwise linked) to the module's shared library? Did you compile the source file with the same compiler flags as the wrapper file? They probably don't have to be identical, but some may be important. My guess that it's not just the constructor; you aren't linking against anything in your non-wrapper cpp file. Jim From hitesh.dhiman.1988 at gmail.com Fri Mar 12 05:01:39 2010 From: hitesh.dhiman.1988 at gmail.com (hitesh dhiman) Date: Fri, 12 Mar 2010 12:01:39 +0800 Subject: [C++-sig] boost.python class constructor error In-Reply-To: <1268365132.1706.3.camel@mu> References: <1268365132.1706.3.camel@mu> Message-ID: hi Jim Will it help if i post my jam-root file? Its included below: import python ; if ! [ python.configured ] { ECHO "notice: no Python configured in user-config.jam" ; ECHO "notice: will use default configuration" ; using python ; } # Specify the path to the Boost project. If you move this project, # adjust this path to refer to the Boost root directory. use-project boost : "C:/Program Files/boost/boost_1_42" ; # Set up the project-wide requirements that everything uses the # boost_python library from the project whose global ID is # /boost/python. project : requirements /boost/python//boost_python ; # Declare the three extension modules. You can specify multiple # source files after the colon separated by spaces. python-extension hello : TestWrap.cpp ; # A little "rule" (function) to clean up the syntax of declaring tests # of these extension modules. local rule run-test ( test-name : sources + ) { import testing ; testing.make-test run-pyd : $(sources) : : $(test-name) ; } >From what you said, its seems the Test1.cpp file needs to be listed under the extension modules, is it? Its as if bjam is totally ignoring Test1.cpp. Any definition/declaration in Test1.cpp file doesn't work. On Fri, Mar 12, 2010 at 11:38 AM, Jim Bosch wrote: > On Fri, 2010-03-12 at 10:36 +0800, hitesh dhiman wrote: > > This error occurs when i declare the class constructor in the c++ > > header file and the definition in the .cpp file. Bjam throws up a > > LNK2019 error, unresolved symbol. > > But if i declare the class constructor in the header file itself, the > > code compiles. > > Here's the code: > > > > > > Test1.h > > #include > > //using namespace std; > > > > > > class World > > { > > public: > > World(); > > ~World(); > > void set(std::string msg) { this->msg = msg; } > > std::string greet() { return msg; } > > std::string msg; > > }; > > > > > > Test1.cpp > > #include "Test1.h" > > > > > > > > > > World::World() {}; > > World::~World() {}; > > int addition(int a, int b) > > { > > int z = a + b; > > return z; > > } > > > > > > Wrapper file: > > #include > > #include "Test1.h" > > > > > > > > > > BOOST_PYTHON_MODULE(hello) > > { > > using namespace boost::python; > > class_("World") > > > > .def("greet", &World::greet) > > .def("set", &World::set) > > ; > > } > > > > > > Is it a compiler bug? I want to define the constructors in the cpp > > file, and not the header file. > > -- > > I've never had any problems doing exactly that, and I can't say more > about your particular situation without seeing your build system setup > (which probably actually wouldn't help me, since I don't know much about > bjam or Windows). > > Are you certain your source file is getting compiled into (or otherwise > linked) to the module's shared library? > > Did you compile the source file with the same compiler flags as the > wrapper file? They probably don't have to be identical, but some may be > important. > > My guess that it's not just the constructor; you aren't linking against > anything in your non-wrapper cpp file. > > > Jim > > > > _______________________________________________ > Cplusplus-sig mailing list > Cplusplus-sig at python.org > http://mail.python.org/mailman/listinfo/cplusplus-sig > -- Regards, Hitesh Dhiman Electrical Engineering National University of Singapore -------------- next part -------------- An HTML attachment was scrubbed... URL: From talljimbo at gmail.com Fri Mar 12 05:48:40 2010 From: talljimbo at gmail.com (Jim Bosch) Date: Thu, 11 Mar 2010 20:48:40 -0800 Subject: [C++-sig] boost.python class constructor error In-Reply-To: References: <1268365132.1706.3.camel@mu> Message-ID: <1268369320.3255.1.camel@bishop> On Fri, 2010-03-12 at 12:01 +0800, hitesh dhiman wrote: > hi Jim > Will it help if i post my jam-root file? Its included below: > import python ; > > > if ! [ python.configured ] > { > ECHO "notice: no Python configured in user-config.jam" ; > ECHO "notice: will use default configuration" ; > using python ; > } > > > # Specify the path to the Boost project. If you move this project, > # adjust this path to refer to the Boost root directory. > use-project boost > : "C:/Program Files/boost/boost_1_42" ; > > > # Set up the project-wide requirements that everything uses the > # boost_python library from the project whose global ID is > # /boost/python. > project > : requirements /boost/python//boost_python ; > > > # Declare the three extension modules. You can specify multiple > # source files after the colon separated by spaces. > python-extension hello : TestWrap.cpp ; > It's this line right here, I think. Should be: python-extension hello : TestWrap.cpp Test1.cpp; Good luck! Jim From hitesh.dhiman.1988 at gmail.com Fri Mar 12 06:18:55 2010 From: hitesh.dhiman.1988 at gmail.com (hitesh dhiman) Date: Fri, 12 Mar 2010 13:18:55 +0800 Subject: [C++-sig] boost.python class constructor error In-Reply-To: <1268369320.3255.1.camel@bishop> References: <1268365132.1706.3.camel@mu> <1268369320.3255.1.camel@bishop> Message-ID: Hi Jim, The solution was to include the Test1.cpp in the python extension line as you suggested. After i had to include include , and the code compiled. I guess the boost documentation is not too clear on these concepts... Anyways thanks for the help! On Fri, Mar 12, 2010 at 12:48 PM, Jim Bosch wrote: > On Fri, 2010-03-12 at 12:01 +0800, hitesh dhiman wrote: > > hi Jim > > Will it help if i post my jam-root file? Its included below: > > import python ; > > > > > > if ! [ python.configured ] > > { > > ECHO "notice: no Python configured in user-config.jam" ; > > ECHO "notice: will use default configuration" ; > > using python ; > > } > > > > > > # Specify the path to the Boost project. If you move this project, > > # adjust this path to refer to the Boost root directory. > > use-project boost > > : "C:/Program Files/boost/boost_1_42" ; > > > > > > # Set up the project-wide requirements that everything uses the > > # boost_python library from the project whose global ID is > > # /boost/python. > > project > > : requirements /boost/python//boost_python ; > > > > > > # Declare the three extension modules. You can specify multiple > > # source files after the colon separated by spaces. > > python-extension hello : TestWrap.cpp ; > > > > It's this line right here, I think. Should be: > > python-extension hello : TestWrap.cpp Test1.cpp; > > > Good luck! > > Jim > > > > > _______________________________________________ > Cplusplus-sig mailing list > Cplusplus-sig at python.org > http://mail.python.org/mailman/listinfo/cplusplus-sig > -- Regards, Hitesh Dhiman Electrical Engineering National University of Singapore -------------- next part -------------- An HTML attachment was scrubbed... URL: From anders.e.e.wallin at gmail.com Sun Mar 14 21:28:11 2010 From: anders.e.e.wallin at gmail.com (Anders Wallin) Date: Sun, 14 Mar 2010 22:28:11 +0200 Subject: [C++-sig] =?windows-1252?q?=91Base=92_is_an_inaccessible_base_of_?= =?windows-1252?q?=91Derived=92_=3F=3F?= Message-ID: <5ce676911003141328p24bd600w50cb32ac246372e@mail.gmail.com> Hi all, I'm trying to expose a base-class with pure virtual functions, and a derived class. Following the example here: http://www.boost.org/doc/libs/1_42_0/libs/python/doc/tutorial/doc/html/python/exposing.html#python.class_virtual_functions both in my real code, and in a minimal test-case, I get a long list of errors which ends with: /usr/include/boost/python/object/inheritance.hpp:99: error: ?Base? is an inaccessible base of ?Derived? my minimal test-case is here: http://pastebin.ca/1839949 This is on stock-standard Ubuntu, i.e. boost 1.38.0, g++ 4,4,1, and python 2.6.4 any ideas what is going on? is there working code for the tutorial-documentation somewhere? thanks, AW From seefeld at sympatico.ca Sun Mar 14 21:49:52 2010 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Sun, 14 Mar 2010 16:49:52 -0400 Subject: [C++-sig] =?windows-1252?q?=91Base=92_is_an_inaccessible_base_of_?= =?windows-1252?q?=91Derived=92_=3F=3F?= In-Reply-To: <5ce676911003141328p24bd600w50cb32ac246372e@mail.gmail.com> References: <5ce676911003141328p24bd600w50cb32ac246372e@mail.gmail.com> Message-ID: <4B9D4BF0.2060807@sympatico.ca> On 03/14/2010 04:28 PM, Anders Wallin wrote: > Hi all, > I'm trying to expose a base-class with pure virtual functions, and a > derived class. Following the example here: > http://www.boost.org/doc/libs/1_42_0/libs/python/doc/tutorial/doc/html/python/exposing.html#python.class_virtual_functions > > both in my real code, and in a minimal test-case, I get a long list of > errors which ends with: > /usr/include/boost/python/object/inheritance.hpp:99: error: ?Base? is > an inaccessible base of ?Derived? > > my minimal test-case is here: > http://pastebin.ca/1839949 > > This is on stock-standard Ubuntu, i.e. boost 1.38.0, g++ 4,4,1, and python 2.6.4 > > any ideas what is going on? is there working code for the > tutorial-documentation somewhere? > The minor but very significant difference between the tutorial code and yours is that the tutorial uses 'struct', while you are using 'class'. The effect is that in your case, all base classes are private, making them, as the compiler says, "inaccessible". Regards, Stefan -- ...ich hab' noch einen Koffer in Berlin... From anders.e.e.wallin at gmail.com Sun Mar 14 22:37:15 2010 From: anders.e.e.wallin at gmail.com (Anders Wallin) Date: Sun, 14 Mar 2010 23:37:15 +0200 Subject: [C++-sig] =?windows-1252?q?=91Base=92_is_an_inaccessible_base_of_?= =?windows-1252?q?=91Derived=92_=3F=3F?= In-Reply-To: <4B9D4BF0.2060807@sympatico.ca> References: <5ce676911003141328p24bd600w50cb32ac246372e@mail.gmail.com> <4B9D4BF0.2060807@sympatico.ca> Message-ID: <5ce676911003141437x3c6d75dfr2c25fbff3301a99d@mail.gmail.com> Thanks, inserting a few "public" keywords here and there makes this compile: class Base { public: virtual int f(int x) = 0; }; class Derived : public Base { public: int f(int x) {return 2*x;} }; class BaseWrap : public Base, public boost::python::wrapper { public: int f(int x) { return this->get_override("f")(x); } }; not sure if this is worth mentioning in the documentation, or is it very obvious to everyone except newbies like myself... :) > The minor but very significant difference between the tutorial code and > yours is that the tutorial uses 'struct', while you are using 'class'. The > effect is that in your case, all base classes are private, making them, as > the compiler says, "inaccessible". > > Regards, > ? ? ? ?Stefan From seefeld at sympatico.ca Sun Mar 14 22:50:54 2010 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Sun, 14 Mar 2010 17:50:54 -0400 Subject: [C++-sig] =?windows-1252?q?=91Base=92_is_an_inaccessible_base_of_?= =?windows-1252?q?=91Derived=92_=3F=3F?= In-Reply-To: <5ce676911003141437x3c6d75dfr2c25fbff3301a99d@mail.gmail.com> References: <5ce676911003141328p24bd600w50cb32ac246372e@mail.gmail.com> <4B9D4BF0.2060807@sympatico.ca> <5ce676911003141437x3c6d75dfr2c25fbff3301a99d@mail.gmail.com> Message-ID: <4B9D5A3E.2030007@sympatico.ca> On 03/14/2010 05:37 PM, Anders Wallin wrote: > not sure if this is worth mentioning in the documentation, or is it > very obvious to everyone except newbies like myself... :) > Knowing that access to base classes and members defaults to 'public' for structs and 'private' for classes is basic C++ knowledge. I don't think there is anything in the tutorial that needs clarification. Regards, Stefan -- ...ich hab' noch einen Koffer in Berlin... From swarfrat at gmail.com Mon Mar 15 20:18:02 2010 From: swarfrat at gmail.com (Nathan Stewart) Date: Mon, 15 Mar 2010 15:18:02 -0400 Subject: [C++-sig] ubuntu/gcc/gccxml Message-ID: <9857ba051003151218u41c08c49uc3f97bf91e960fc2@mail.gmail.com> I'm trying to use pyplusplus, and I'm running into what appears to be a really old problem fixed by the gccxml-0.9.0+cvs20080525 patch. I'm running Ubuntu 9.10, gcc-4.4.1, gccxml 0.9.0+cvs20080525. I'm also a little confused by the various versions of gccxml out there - the 'official' site claims 0.6 is the latest. The language-binding.net site refers to version 0.9. Basically pyplusplus has never worked (out of the box or with any amount of fiddling) on karmic for me, on any of my machines. The errors I get are: Error occured while running GCC-XML: In file included from /usr/include/fcntl.h:217,... And lots more errors in fctnl2.h ' __builtin_va_arg_pack_len' not declared in this scope. I have tried running GCC-XML w/ gcc-4.2, modifying headers as in some of the other posts, to no avail. Is there anyone with a Karmic box that has this working at all? -------------- next part -------------- An HTML attachment was scrubbed... URL: From roman.yakovenko at gmail.com Mon Mar 15 20:58:10 2010 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Mon, 15 Mar 2010 21:58:10 +0200 Subject: [C++-sig] ubuntu/gcc/gccxml In-Reply-To: <9857ba051003151218u41c08c49uc3f97bf91e960fc2@mail.gmail.com> References: <9857ba051003151218u41c08c49uc3f97bf91e960fc2@mail.gmail.com> Message-ID: <7465b6171003151258t61f87a39xb18135551aa8388a@mail.gmail.com> On 3/15/10, Nathan Stewart wrote: > I'm trying to use pyplusplus, and I'm running into what appears to be a > really old problem fixed by the gccxml-0.9.0+cvs20080525 patch. > > I'm running Ubuntu 9.10, gcc-4.4.1, gccxml 0.9.0+cvs20080525. I'm also a > little confused by the various versions of gccxml out there - the 'official' > site claims 0.6 is the latest. The language-binding.net site refers to > version 0.9. The latest official GCCXML release was indeed 0.6, since then the only way to get it is to compile and install from sources. GCCXML version 0.6 is based on gcc-3.6 ( I could be wrong ), while the current sources are based on gcc-4.2 > Basically pyplusplus has never worked (out of the box or with > any amount of fiddling) on karmic for me, on any of my machines. > > The errors I get are: > > Error occured while running GCC-XML: In file included from > /usr/include/fcntl.h:217,... > And lots more errors in fctnl2.h ' __builtin_va_arg_pack_len' not declared > in this scope. > > I have tried running GCC-XML w/ gcc-4.2, modifying headers as in some of the > other posts, to no avail. I suggest you to take this problem to gccxml mailing list, with complete gccxml command line invocation. You can find it in the output, produced by py++. I am sure you will get the help and the solution. ( I did and it was really quick ). > Is there anyone with a Karmic box that has this working at all? I am using and testing py++ and pygccxml on Ubuntu 9.10 32/64 architectures with gcc-4.4.1 as the default compiler. pygccxml svn contains compiled gccxml for those architectures ( http://pygccxml.svn.sourceforge.net/viewvc/pygccxml/gccxml_bin/v09/ ) and used for testing. HTH -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From faboster at gmail.com Tue Mar 16 04:25:41 2010 From: faboster at gmail.com (Fabzter) Date: Mon, 15 Mar 2010 21:25:41 -0600 Subject: [C++-sig] Having problems with returned object. Message-ID: Hi everybody, I'll try to describe my problem: I have this c++ class (simplyfied): ------------------------------------------------------------------------------------------- class MyClass { public: MyClass() { this->setPos(0, 0); } MyClass(const MyClass& orig) { this->setPos(orig.pos); } void setPos(int x, int y) { this->pos.clear(); this->pos.push_back(x); this->pos.push_back(y); } void setPos(const std::vector& p) { this->pos = p; } const std::vector& getPos() const { return this->pos; } private: std::vector pos; }; ------------------------------------------------------------------------------------------- And then, it's wrapped like this: ------------------------------------------------------------------------------------------- typedef void (MyClass::*setPos_with_int)(int x, int y); typedef void (MyClass::*setPos_with_vect)(const std::vector& pos); void export_jugada() { class_("MyClass") .def("setPos", setPosicion_with_int(&MyClass::setPos) ) .def("setPos", setPosicion_with_vect(&MyClass::setPos) ) .def("getPosicion", &MyClass::getPosicion, return_value_policy()) ; } ------------------------------------------------------------------------------------------- Now, I have a little script that does something like: ------------------------------------------------------------------------------------------- ... def get() m = MyClass() m.setPos(4, 9) return m ... ------------------------------------------------------------------------------------------- I have debugged (as much as my knowledge lets me!!!) to this point and everything seem fine. "get()" gets properly called, and when it calls MyClass::setPos(int, int), it seems to do everything fine (filling up the vector). Well, now, in the main program, after reading the script, I do something like this: ------------------------------------------------------------------------------------------- ...extracting get() from script... MyClass m ( getObj() ); ------------------------------------------------------------------------------------------- The problem here is that m ends up having pos = {4, 0}. The second element from the vector is ALWAYS == 0. While debugging I discovered that when the returned object is being copied (via copy constructor), the "pos" member of the origin (the object that came from python) has, well, it's second element == 0. The same happens if I do something like: ------------------------------------------------------------------------------------------- ...extracting get() from script... MyClass m = getObj() ; ------------------------------------------------------------------------------------------- Please, help me find my mistakes, I've already spent hours trying to solve this :( From alexandre.hamez at gmail.com Tue Mar 16 12:10:39 2010 From: alexandre.hamez at gmail.com (Alexandre Hamez) Date: Tue, 16 Mar 2010 12:10:39 +0100 Subject: [C++-sig] Ownership of a C++ object extended in Python using wrapper Message-ID: Hi all, I have a C++ library that needs to store in a hash map user's code, that is, Python-extended objects. To make the C++ interface available to Python, I use boost::python::wrapper, as stated in the tutorial (http://www.boost.org/doc/libs/1_42_0/libs/python/doc/tutorial/doc/html/python/exposing.html#python.class_virtual_functions). Because I store this extend objects, I need to tell Python that I've got a reference on these objects. A thread from 2007 (http://mail.python.org/pipermail/cplusplus-sig/2007-March/011790.html) states there is a problem for this particular use case, but in the end, no solution is given. So my question is the following: as of today, what is the correct way to tell Python we hold a reference to Python extend objects of C++ classes, using the boost::python::wrapper mechanism? Thanks, --------------------- Alexandre Hamez From ndbecker2 at gmail.com Tue Mar 16 13:12:21 2010 From: ndbecker2 at gmail.com (Neal Becker) Date: Tue, 16 Mar 2010 08:12:21 -0400 Subject: [C++-sig] Ownership of a C++ object extended in Python using wrapper References: Message-ID: Alexandre Hamez wrote: > Hi all, > > I have a C++ library that needs to store in a hash map user's code, that > is, Python-extended objects. To make the C++ interface available to > Python, I use boost::python::wrapper, as stated in the tutorial > (http://www.boost.org/doc/libs/1_42_0/libs/python/doc/tutorial/doc/html/python/exposing.html#python.class_virtual_functions). > Because I store this extend objects, I need to tell Python that I've got a > reference on these objects. > A thread from 2007 > (http://mail.python.org/pipermail/cplusplus-sig/2007-March/011790.html) > states there is a problem for this particular use case, but in the end, no > solution is given. So my question is the following: as of today, what is > the correct way to tell Python we hold a reference to Python extend > objects of C++ classes, using the boost::python::wrapper mechanism? > > Thanks, > --------------------- > Alexandre Hamez I've use 2 methods: 1) with_custodian_and_ward 2) boost::shared_ptr From alexandre.hamez at gmail.com Tue Mar 16 20:56:42 2010 From: alexandre.hamez at gmail.com (Alexandre Hamez) Date: Tue, 16 Mar 2010 20:56:42 +0100 Subject: [C++-sig] Ownership of a C++ object extended in Python using wrapper In-Reply-To: References: Message-ID: <5E733D3E-FD54-46F4-B8F3-484F6DC113C7@gmail.com> On 16 mars 2010, at 13:12, Neal Becker wrote: > Alexandre Hamez wrote: > >> Hi all, >> >> I have a C++ library that needs to store in a hash map user's code, that >> is, Python-extended objects. To make the C++ interface available to >> Python, I use boost::python::wrapper, as stated in the tutorial >> > (http://www.boost.org/doc/libs/1_42_0/libs/python/doc/tutorial/doc/html/python/exposing.html#python.class_virtual_functions). >> Because I store this extend objects, I need to tell Python that I've got a >> reference on these objects. >> A thread from 2007 >> (http://mail.python.org/pipermail/cplusplus-sig/2007-March/011790.html) >> states there is a problem for this particular use case, but in the end, no >> solution is given. So my question is the following: as of today, what is >> the correct way to tell Python we hold a reference to Python extend >> objects of C++ classes, using the boost::python::wrapper mechanism? >> >> Thanks, >> --------------------- >> Alexandre Hamez > Thanks for answering so quickly. > I've use 2 methods: > > 1) with_custodian_and_ward OK, I didn't think of this method. Seems a good way to do it. > 2) boost::shared_ptr For this point, do you mean you just take the objects that should seen they references increased by a shared_ptr? Just after having asked this question, I tried with this simple solution, and it seems to work. I hope there is no hidden potential crash :-) Do you use these two methods conjointly in the same project? Or did you identify some use cases which favor a method rather the other one? --------------------- Alexandre Hamez From talljimbo at gmail.com Tue Mar 16 22:21:51 2010 From: talljimbo at gmail.com (Jim Bosch) Date: Tue, 16 Mar 2010 14:21:51 -0700 Subject: [C++-sig] Ownership of a C++ object extended in Python using wrapper In-Reply-To: <5E733D3E-FD54-46F4-B8F3-484F6DC113C7@gmail.com> References: <5E733D3E-FD54-46F4-B8F3-484F6DC113C7@gmail.com> Message-ID: <1268774511.16184.11.camel@mu> On Tue, 2010-03-16 at 20:56 +0100, Alexandre Hamez wrote: > On 16 mars 2010, at 13:12, Neal Becker wrote: > > > Alexandre Hamez wrote: > > > >> Hi all, > >> > >> I have a C++ library that needs to store in a hash map user's code, that > >> is, Python-extended objects. To make the C++ interface available to > >> Python, I use boost::python::wrapper, as stated in the tutorial > >> > > (http://www.boost.org/doc/libs/1_42_0/libs/python/doc/tutorial/doc/html/python/exposing.html#python.class_virtual_functions). > >> Because I store this extend objects, I need to tell Python that I've got a > >> reference on these objects. > >> A thread from 2007 > >> (http://mail.python.org/pipermail/cplusplus-sig/2007-March/011790.html) > >> states there is a problem for this particular use case, but in the end, no > >> solution is given. So my question is the following: as of today, what is > >> the correct way to tell Python we hold a reference to Python extend > >> objects of C++ classes, using the boost::python::wrapper mechanism? > >> > >> Thanks, > >> --------------------- > >> Alexandre Hamez > > > > Thanks for answering so quickly. > > I've use 2 methods: > > > > 1) with_custodian_and_ward > OK, I didn't think of this method. Seems a good way to do it. > > > 2) boost::shared_ptr > > For this point, do you mean you just take the objects that should seen they references increased by a shared_ptr? Just after having asked this question, I tried with this simple solution, and it seems to work. I hope there is no hidden potential crash :-) > If you get a boost::shared_ptr to a Python object (either by wrapping a function taking a shared_ptr or by using boost::python::extract), that shared_ptr will properly manage the Python reference count via a custom deleter that decref's the PyObject* when it goes out of scope. The only catch is that shared_ptr doesn't do garbage collection, so you can get cycles that don't get deleted if your shared_ptrs own other shared_ptrs. Other than that, you're should be safe if you just use shared_ptr everywhere. This will work differently internally if you declare your wrapped classes to have shared_ptr storage (that's generally what I do), but the effects should be mostly the same. Note that you can also declare your storage to be shared_ptr to a wrapper class. > Do you use these two methods conjointly in the same project? Or did you identify some use cases which favor a method rather the other one? > I generally use shared_ptr storage for everything, but I often mix that with with_custodian_and_ward and its cousins (return_internal_reference, in particular) when I don't have access to a shared_ptr on the C++ side. Jim Bosch From macieksitarz at wp.pl Wed Mar 17 08:38:51 2010 From: macieksitarz at wp.pl (Maciej Sitarz) Date: Wed, 17 Mar 2010 08:38:51 +0100 Subject: [C++-sig] Py++ - one header file including all project header files Message-ID: <4BA0870B.9090605@wp.pl> Hello, I'm attempting to create python module for CREAM Client API (http://grid.pd.infn.it/cream/). After reading Py++ "best practices" I tried to include all needed headers into one and then add it to Py++. But then the resulting .cpp file doesn't have any wrappers inside, only for one function which was declared directly in that one header file. What is possibly wrong in my approach? Here are the scripts based on pyogre project: http://fatcat.ftj.agh.edu.pl/~sitarzm/pycream/pycream_module_20100317.tar.bz2 Thanks, -- Maciek Sitarz From roman.yakovenko at gmail.com Wed Mar 17 08:52:54 2010 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Wed, 17 Mar 2010 09:52:54 +0200 Subject: [C++-sig] Py++ - one header file including all project header files In-Reply-To: <4BA0870B.9090605@wp.pl> References: <4BA0870B.9090605@wp.pl> Message-ID: <7465b6171003170052j7b89313at5a6901445f33c096@mail.gmail.com> On Wed, Mar 17, 2010 at 9:38 AM, Maciej Sitarz wrote: > Hello, > > I'm attempting to create python module for CREAM Client API > (http://grid.pd.infn.it/cream/). > > After reading Py++ "best practices" I tried to include all needed headers > into one and then add it to Py++. But then the resulting .cpp file doesn't > have any wrappers inside, only for one function which was declared directly > in that one header file. > > What is possibly wrong in my approach? Nothing, really. Please take a look on the following document: http://language-binding.net/pyplusplus/documentation/tutorials/module_builder/module_builder.html#declarations-customization and let me know whether is makes sense to you. If not come back and we will resolve the issue -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From ndbecker2 at gmail.com Wed Mar 17 12:57:14 2010 From: ndbecker2 at gmail.com (Neal Becker) Date: Wed, 17 Mar 2010 07:57:14 -0400 Subject: [C++-sig] Ownership of a C++ object extended in Python using wrapper References: <5E733D3E-FD54-46F4-B8F3-484F6DC113C7@gmail.com> Message-ID: Alexandre Hamez wrote: > > On 16 mars 2010, at 13:12, Neal Becker wrote: > >> Alexandre Hamez wrote: >> >>> Hi all, >>> >>> I have a C++ library that needs to store in a hash map user's code, that >>> is, Python-extended objects. To make the C++ interface available to >>> Python, I use boost::python::wrapper, as stated in the tutorial >>> >> (http://www.boost.org/doc/libs/1_42_0/libs/python/doc/tutorial/doc/html/python/exposing.html#python.class_virtual_functions). >>> Because I store this extend objects, I need to tell Python that I've got >>> a reference on these objects. >>> A thread from 2007 >>> (http://mail.python.org/pipermail/cplusplus-sig/2007-March/011790.html) >>> states there is a problem for this particular use case, but in the end, >>> no solution is given. So my question is the following: as of today, what >>> is >>> the correct way to tell Python we hold a reference to Python extend >>> objects of C++ classes, using the boost::python::wrapper mechanism? >>> >>> Thanks, >>> --------------------- >>> Alexandre Hamez >> > > Thanks for answering so quickly. >> I've use 2 methods: >> >> 1) with_custodian_and_ward > OK, I didn't think of this method. Seems a good way to do it. > >> 2) boost::shared_ptr > > For this point, do you mean you just take the objects that should seen > they references increased by a shared_ptr? Just after having asked this > question, I tried with this simple solution, and it seems to work. I hope > there is no hidden potential crash :-) > > Do you use these two methods conjointly in the same project? Or did you > identify some use cases which favor a method rather the other one? > Looking at some of my old code, I'd say I used one method or the other depending on the phase of the moon. Haven't mixed them (sounds like a bad idea). From alexandre.hamez at gmail.com Wed Mar 17 17:14:15 2010 From: alexandre.hamez at gmail.com (Alexandre Hamez) Date: Wed, 17 Mar 2010 17:14:15 +0100 Subject: [C++-sig] Ownership of a C++ object extended in Python using wrapper In-Reply-To: <1268774511.16184.11.camel@mu> References: <5E733D3E-FD54-46F4-B8F3-484F6DC113C7@gmail.com> <1268774511.16184.11.camel@mu> Message-ID: On 16 mars 2010, at 22:21, Jim Bosch wrote: > On Tue, 2010-03-16 at 20:56 +0100, Alexandre Hamez wrote: >> On 16 mars 2010, at 13:12, Neal Becker wrote: >> >>> Alexandre Hamez wrote: >>> >>>> Hi all, >>>> >>>> I have a C++ library that needs to store in a hash map user's code, that >>>> is, Python-extended objects. To make the C++ interface available to >>>> Python, I use boost::python::wrapper, as stated in the tutorial >>>> >>> (http://www.boost.org/doc/libs/1_42_0/libs/python/doc/tutorial/doc/html/python/exposing.html#python.class_virtual_functions). >>>> Because I store this extend objects, I need to tell Python that I've got a >>>> reference on these objects. >>>> A thread from 2007 >>>> (http://mail.python.org/pipermail/cplusplus-sig/2007-March/011790.html) >>>> states there is a problem for this particular use case, but in the end, no >>>> solution is given. So my question is the following: as of today, what is >>>> the correct way to tell Python we hold a reference to Python extend >>>> objects of C++ classes, using the boost::python::wrapper mechanism? >>>> >>>> Thanks, >>>> --------------------- >>>> Alexandre Hamez >>> >> >> Thanks for answering so quickly. >>> I've use 2 methods: >>> >>> 1) with_custodian_and_ward >> OK, I didn't think of this method. Seems a good way to do it. >> >>> 2) boost::shared_ptr >> >> For this point, do you mean you just take the objects that should seen they references increased by a shared_ptr? Just after having asked this question, I tried with this simple solution, and it seems to work. I hope there is no hidden potential crash :-) >> > > If you get a boost::shared_ptr to a Python object (either by wrapping a > function taking a shared_ptr or by using boost::python::extract), that > shared_ptr will properly manage the Python reference count via a custom > deleter that decref's the PyObject* when it goes out of scope. The only > catch is that shared_ptr doesn't do garbage collection, so you can get > cycles that don't get deleted if your shared_ptrs own other shared_ptrs. > Other than that, you're should be safe if you just use shared_ptr > everywhere. > > This will work differently internally if you declare your wrapped > classes to have shared_ptr storage (that's generally what I do), but the > effects should be mostly the same. Note that you can also declare your > storage to be shared_ptr to a wrapper class. > >> Do you use these two methods conjointly in the same project? Or did you identify some use cases which favor a method rather the other one? >> > > I generally use shared_ptr storage for everything, but I often mix that > with with_custodian_and_ward and its cousins (return_internal_reference, > in particular) when I don't have access to a shared_ptr on the C++ side. > > > Jim Bosch > > _______________________________________________ > Cplusplus-sig mailing list > Cplusplus-sig at python.org > http://mail.python.org/mailman/listinfo/cplusplus-sig OK, thank you very much for your answer! --------------------- Alexandre Hamez From ndbecker2 at gmail.com Wed Mar 17 19:57:40 2010 From: ndbecker2 at gmail.com (Neal Becker) Date: Wed, 17 Mar 2010 14:57:40 -0400 Subject: [C++-sig] Ownership of a C++ object extended in Python using wrapper References: <5E733D3E-FD54-46F4-B8F3-484F6DC113C7@gmail.com> <1268774511.16184.11.camel@mu> Message-ID: One tradeoff, I believe, If you have, say: class A { A (boost::shared_ptr) boost::shared_ptr B_obj; }; Then each time you use B_obj, there is additional dereference overhead IIUC. If I used with_custodian_and_ward, there should not be this additional overhead. From rogeeff at gmail.com Wed Mar 17 23:21:43 2010 From: rogeeff at gmail.com (Gennadiy Rozental) Date: Wed, 17 Mar 2010 22:21:43 +0000 (UTC) Subject: [C++-sig] errors while setting arguments description for the method Message-ID: I've got specification like this: class_( "Foo", "Foo descr" ) .def( "__init__", bp::make_constructor( &make_foo ), bp::args( "self", "str" ), "Constructor based on string representation.\n" ) ... I am getting compilation error below from VC9.0. Error disappears if I avoid bp::args( "self", "str" ) part. Please advise, Gennadiy 1>...\boost-1.39\boost/python/def_visitor.hpp(43) : error C2784: 'void boost::python::api::object_operators::visit(ClassT &,const char *,const boost::python::detail::def_helper &) const' : could not deduce template argument for 'const boost::python::detail::def_helper &' from 'const boost::python::detail::def_helper' 1> with 1> [ 1> U=boost::python::api::object 1> ] 1> and 1> [ 1> T1=boost::python::detail::keywords<2>, 1> T2=const char [106] 1> ] 1> ....\boost-1.39\boost/python/object_core.hpp(188) : see declaration of 'boost::python::api::object_operators::visit' 1> with 1> [ 1> U=boost::python::api::object 1> ] 1> ....\boost-1.39\boost/python/def_visitor.hpp(74) : see reference to function template instantiation 'void boost::python::def_visitor_access::visit,classT,OptionalArgs>(const V &,classT &,const char *, const OptionalArgs &)' being compiled 1> with 1> [ 1> DerivedVisitor=boost::python::api::object, 1> classT=boost::python::class_, 1> OptionalArgs=boost::python::detail::def_helper,const char [106]>, 1> V=boost::python::def_visitor 1> ] 1 ...\boost-1.39\boost/python/class.hpp(524) : see reference to function template instantiation 'void boost::python::def_visitor::visit,Helper>(classT &,const char *,const OptionalArgs &)const' being compiled 1> with 1> [ 1> DerivedVisitor=boost::python::api::object, 1> W=Foo, 1> X1=FooSP, 1> X2=boost::python::detail::not_specified, 1> X3=boost::python::detail::not_specified, 1> Helper=boost::python::detail::def_helper, const char [106]>, 1> classT=boost::python::class_, 1> OptionalArgs=boost::python::detail::def_helper,const char [106]> 1> ] 1> ...\boost-1.39\boost/python/class.hpp(259) : see reference to function template instantiation 'void boost::python::class_::def_impl,Fn,U>(T *,const char *,LeafVisitor,const Helper &,const boost::python::def_visitor *)' being compiled 1> with 1> [ 1> W=Foo, 1> X1=FooSP, 1> X2=boost::python::detail::not_specified, 1> X3=boost::python::detail::not_specified, 1> T1=boost::python::detail::keywords<2>, 1> T2=const char [106], 1> Fn=boost::python::api::object, 1> U=boost::python::api::object, 1> T=Foo, 1> LeafVisitor=boost::python::api::object, 1> Helper=boost::python::detail::def_helper,const char [106]>, 1> DerivedVisitor=boost::python::api::object 1> ] 1> .\src\my_export.cpp(422) : see reference to function template instantiation 'boost::python::class_ &boost::python::class_::def,const char[106]>(const char *, Fn,const A1 &,A2 (&))' being compiled 1> with 1> [ 1> W=Foo, 1> X1=FooSP, 1> X2=boost::python::detail::not_specified, 1> X3=boost::python::detail::not_specified, 1> nkeywords=2, 1> Fn=boost::python::api::object, 1> A1=boost::python::detail::keywords<2>, 1> A2=const char [106] 1> ] From talljimbo at gmail.com Wed Mar 17 23:30:19 2010 From: talljimbo at gmail.com (Jim Bosch) Date: Wed, 17 Mar 2010 15:30:19 -0700 Subject: [C++-sig] errors while setting arguments description for the method In-Reply-To: References: Message-ID: <1268865019.24006.4.camel@mu> On Wed, 2010-03-17 at 22:21 +0000, Gennadiy Rozental wrote: > I've got specification like this: > > class_( "Foo", "Foo descr" ) > .def( "__init__", bp::make_constructor( &make_foo ), > bp::args( "self", "str" ), > "Constructor based on string representation.\n" ) > ... > > I am getting compilation error below from VC9.0. Error disappears if I avoid > bp::args( "self", "str" ) part. > > Please advise, > You have to pass the keywords to make_constructor: .def("__init__", bp::make_constructor(&make_foo, bp::default_call_policies(), bp::args("self","str")) ) I'm not actually sure whether to put the docstring in the call to make_constructor (I'll let you experiment), but you do have to supply the call policies argument manually if you want to supply keywords - make_constructor just doesn't have the overloads that make_function does. Jim Bosch From talljimbo at gmail.com Wed Mar 17 23:48:01 2010 From: talljimbo at gmail.com (Jim Bosch) Date: Wed, 17 Mar 2010 15:48:01 -0700 Subject: [C++-sig] Having problems with returned object. In-Reply-To: References: Message-ID: <1268866081.24174.9.camel@mu> On Mon, 2010-03-15 at 21:25 -0600, Fabzter wrote: > void export_jugada() > { > class_("MyClass") > .def("setPos", setPosicion_with_int(&MyClass::setPos) ) > .def("setPos", setPosicion_with_vect(&MyClass::setPos) ) > > .def("getPosicion", &MyClass::getPosicion, > return_value_policy()) > ; > } Unless you've also wrapped std::vector, I don't think your getPosicion() wrapper will work in Python (it should throw an exception when you call it). And by the way, you probably want "return_internal_reference<>" instead of "reference_existing_object" to be a little safer - that tells Python your MyClass instance owns the vector, rather than stating "I promise this reference will stay valid". > ------------------------------------------------------------------------------------------- > > Now, I have a little script that does something like: > > ------------------------------------------------------------------------------------------- > ... > def get() > m = MyClass() > m.setPos(4, 9) > return m > ... > ------------------------------------------------------------------------------------------- > > I have debugged (as much as my knowledge lets me!!!) to this point and > everything seem fine. "get()" gets properly called, and when it calls > MyClass::setPos(int, int), it seems to do everything fine (filling up > the vector). Well, now, in the main program, after reading the script, > I do something like this: > > ------------------------------------------------------------------------------------------- > ...extracting get() from script... > MyClass m ( getObj() ); > ------------------------------------------------------------------------------------------- > I don't really understand what you're doing here. Where is getObj() defined, and what does it do? I gather that your "main program" is written in C++, not Python - are you embedding? I'm not sure the std::vector stuff above is related to your problem, but without knowing more I can't say. Jim Bosch From hitesh.dhiman.1988 at gmail.com Thu Mar 18 04:39:44 2010 From: hitesh.dhiman.1988 at gmail.com (hitesh dhiman) Date: Thu, 18 Mar 2010 11:39:44 +0800 Subject: [C++-sig] passing pointers from python Message-ID: Hi all, i'm trying to wrap c++ functions that have pointer variables. The test example i'm using is shown below: int World::addition(int* a, int* b) { int z = *a + *b; return z; } Now, i defined it in my wrapper as : .def("addition", &World::addition) My code compiles, but when I try to execute it from python, i get this error: Python Argument types in World.Addition(World, int, int) did not match C++ signature: addition(class World {lvalue}, int* , int*) The problem is, how to get hold of a pointer in python? Or is there a workaround to define the function differently in the wrapper file? -- Regards, Hitesh Dhiman Electrical Engineering National University of Singapore -------------- next part -------------- An HTML attachment was scrubbed... URL: From swarfrat at gmail.com Thu Mar 18 04:53:17 2010 From: swarfrat at gmail.com (Nathan Stewart) Date: Wed, 17 Mar 2010 23:53:17 -0400 Subject: [C++-sig] Overriding Virtual Functions Message-ID: <9857ba051003172053q58359e4ds2defac2d76345e0b@mail.gmail.com> I have a C++ class like so: namespace Foo { class TypeA {}; class TypeB {}; class Connection { template void Publish(const T&); virtual void OnEvent(const TypeA&) {} virtual void OnEvent(const TypeB&) {} }; } I've exported it like so: namespace { class ConnectionWrap : public Foo::Connection, wrapper { virtual void OnEvent(const TypeA& event) { if (override f = get_override("OnEvent_TypeA")) { f(event); } // no need to call Connection::OnEvent since it does nothing } virtual void OnEvent(const TypeB& event) { if (override f = get_override("OnEvent_TypeB")) { f(event); } // no need to call Connection::OnEvent since it does nothing } }; } BOOST_PYTHON_MODULE(_mypywrap) { class_("Connection") .def("Publish", &ConnectionWrap::Publish) .def("Publish", &ConnectionWrap::Publish) ; } It compiles, imports, etc.. However if I remove .def("Publish", &ConnectionWrap::Publish), and I try: import _mypywrap connection = _mypywrap.Connection() # ok connection.Publish(_mypywrap.TypeA()) # not ok but expected. The error msg is "Connection.Publish(Connection, TypeA) did not match C++ signature:..." and it dumps a list of signatures it knows about which would be "publish(Foo::Connection {lvalue}, Foo::TypeB)" if I instead do the following: connection.Publish(_mypywrap.TypeB()) I get a seg fault, looking at the stack trace shows it blew up in get_override(char const*, _typeobject*) const, and if I go to that frame, both arguments have been optimized out. Whew. So my questions are: (besides what am I doing wrong - unless that's easier to answer) In the first example where I did not export the first publish, it failed as expected. However the namespaces are not consistent between the signature attempted to match and the known signatures. I'm puzzled by that, but I suspect its just a formatting difference - since the second example actually does call publish (which I know because the stack trace shows me it received a message from the C++ class and blew up trying to jump the chasm back into python land). Am I doing something wrong with the namespaces here, and is that why my functions aren't visible? In the second example... I know that the python function "OnEvent_TypeB" hasn't been created. I don't get why it blows up in get_override rather than fails. The other examples I've found indicate that I should be able to use that mechanism to provide access to the base class virtual functions which do have bodies. In fact, I'm running into this problem with my ConnectionWrap class, not something derived from it. Does the override need to exist, and if so, how can I accomplish this goal (of only overriding behavior I want to implement)? -------------- next part -------------- An HTML attachment was scrubbed... URL: From faboster at gmail.com Thu Mar 18 05:42:35 2010 From: faboster at gmail.com (Fabzter) Date: Wed, 17 Mar 2010 22:42:35 -0600 Subject: [C++-sig] Executing scripts in other namespace than __main__ Message-ID: Hi everybody, it's my annoying again. I have a pure virtual class in C++ wich I have wrapped and exposed (call it BaseClass), and I let the users inherit from it to make their own class in their script. It's worth noting that I do not know the name of such class they are creating. When I load only one script, there's no problem in doing this: ___________________________________________ object module_main = import("__main__"); object namespace_module_main = module_main.attr("__dict__"); exec("import sys\n", namespace_module_main, namespace_module_main); object ignored = exec_file(boost::python::str("path/file1.py"), namespace_module_main, namespace_module_main); //and as i don't know how the class they defined was named... object ignored_ = exec("l = dir()\n" //get everything defined in current dictionary "class_ = None\n" "for i in l:\n" " res = eval(i)\n" " if type(res) == type(BaseClass): class_ = res\n" //if we've got a class derived from BaseClass, we save it to "class_" "if class_ is None: raise Error()\n" , this->namespace_modulo_local, this->namespace_modulo_local); object class_ = namespace_module_main["class_"]; //get the class object object instance_ = class_(); BaseClass *bc = extract(instance_); ___________________________________________ This works quite well when I only load one module. But if I load 2 or more modules, the method I use to extract a class derived from BaseClass is useless, since there are two or more classes derived from BaseClass in __main__ and I don't know which one I will get. So I thought I could run each script in it's own namespace, and then using the same method for retrieving the class, but in every individual namespace, ensuring I will get the derived class from the specified script. How can I acommplish this? (: From faboster at gmail.com Thu Mar 18 15:25:21 2010 From: faboster at gmail.com (Fabzter) Date: Thu, 18 Mar 2010 08:25:21 -0600 Subject: [C++-sig] Having problems with returned object. In-Reply-To: References: Message-ID: Thank you. My problems was obviously not about std::vector, since I had already wrapped it. And sorry for my bad formed example, I was in some kind of hurry while writing it. Anyways, I already solved this problem, sorry for my former lack of detail. From alexandre.hamez at gmail.com Thu Mar 18 17:01:44 2010 From: alexandre.hamez at gmail.com (Alexandre Hamez) Date: Thu, 18 Mar 2010 17:01:44 +0100 Subject: [C++-sig] Loosing real python type in Python extend class Message-ID: <5B0FEFF7-9DFB-44ED-82B7-658631477E9C@gmail.com> Hello, If I have a (pure virtual) class foo that I expose in order to be extended in Python: > struct foo_wrap > : public foo > , public wrapper > { > > bool > operator==( const foo& rhs ) > const > { > return this->get_override("__eq__")(rhs); > } > > }; > > BOOST_PYTHON_MODULE(module) > { > > class_< foo_wrap >("Foo") > .def("__eq__" , pure_virtual(&function::operator== )) > ; > } Now in Python: > class Bar(module.Foo): > > def __init__( self ): > super(Bar,self).__init__() > > def __eq__(self,other): > if not isinstance( other, Bar): > # Always false!!!! > return False > else: > # some test If the 'other' parameter is given by the C++ side, then the type that __eq__ sees is 'module.Foo'. Is there a way to give to the __eq__ method the real python type? I suppose I can use a to_python_converter, but I'm not sure how to do this. Thank you! --------------------- Alexandre Hamez From faboster at gmail.com Thu Mar 18 18:49:38 2010 From: faboster at gmail.com (Fabzter) Date: Thu, 18 Mar 2010 11:49:38 -0600 Subject: [C++-sig] Executing scripts in other namespace than __main__ In-Reply-To: References: Message-ID: Hi. The only way I could deal with this issue was to keep track of every class derived from the BaseClass, in order to _not_ using it again to instantiate an object. I changed this: > exec("import sys\n", namespace_module_main, > namespace_module_main); to: > exec("import sys\n classes = []\n", namespace_module_main, > namespace_module_main); and: > object ignored_ = > exec("l = dir()\n" //get everything defined in current dictionary > "class_ = None\n" > "for i in l:\n" > " res = eval(i)\n" > " if type(res) == type(BaseClass): class_ = res\n" > //if we've got a class derived from BaseClass, we save it to "class_" > "if class_ is None: raise Error()\n" > , this->namespace_modulo_local, this->namespace_modulo_local); to: > object ignored_ = > exec("l = dir()\n" //get everything defined in current dictionary > "class_ = None\n" > "for i in l:\n" > " res = eval(i)\n" > " if type(res) == type(BaseClass) and res not in classes:\n > " class_ = res\n" > " classes.append( res); break\n" > //if we've got a class derived from BaseClass, we save it to "class_" > "if class_ is None: raise Error()\n" > , this->namespace_modulo_local, this->namespace_modulo_local); And it works quite well for my purposes, but I would like to know if there's a more elegant way to extract a class which I know its base class, but not its name. From swarfrat at gmail.com Thu Mar 18 19:35:18 2010 From: swarfrat at gmail.com (Nathan Stewart) Date: Thu, 18 Mar 2010 14:35:18 -0400 Subject: [C++-sig] Overriding Virtual Functions In-Reply-To: <9857ba051003172053q58359e4ds2defac2d76345e0b@mail.gmail.com> References: <9857ba051003172053q58359e4ds2defac2d76345e0b@mail.gmail.com> Message-ID: <9857ba051003181135o70bbc362rb26afe577e33051c@mail.gmail.com> On Wed, Mar 17, 2010 at 11:53 PM, Nathan Stewart wrote: > In the second example... I know that the python function "OnEvent_TypeB" > hasn't been created. I don't get why it blows up in get_override rather > than fails. The other examples I've found indicate that I should be able to > use that mechanism to provide access to the base class virtual functions > which do have bodies. In fact, I'm running into this problem with my > ConnectionWrap class, not something derived from it. Does the override need > to exist, and if so, how can I accomplish this goal (of only overriding > behavior I want to implement)? > > On further exploration, I'm wondering if this is not a threading issue rather than a virtual function override issue, given that my example is a callback system, however my base Connection class has it's own locking that prevents publish and onEvent from being run at the same time. -------------- next part -------------- An HTML attachment was scrubbed... URL: From macieksitarz at wp.pl Fri Mar 19 00:27:50 2010 From: macieksitarz at wp.pl (Maciej Sitarz) Date: Fri, 19 Mar 2010 00:27:50 +0100 Subject: [C++-sig] Py++ - one header file including all project header files In-Reply-To: <7465b6171003170052j7b89313at5a6901445f33c096@mail.gmail.com> References: <4BA0870B.9090605@wp.pl> <7465b6171003170052j7b89313at5a6901445f33c096@mail.gmail.com> Message-ID: <4BA2B6F6.1060307@wp.pl> On 17.03.2010 08:52, Roman Yakovenko wrote: > Nothing, really. > > Please take a look on the following document: > http://language-binding.net/pyplusplus/documentation/tutorials/module_builder/module_builder.html#declarations-customization > and let me know whether is makes sense to you. > > If not come back and we will resolve the issue Thanks, I added this two loops for ex/including some classes and now it works as it should. # Include Cream CE classes for class_name in environment.include_classes: print "Including class '%s'" % class_name mb.class_( name=class_name ).include() # Exclude Cream CE classes for class_name in environment.exclude_classes: print "Excluding class '%s'" % class_name mb.class_( name=class_name ).exclude() Best regards -- Maciek Sitarz From hitesh.dhiman.1988 at gmail.com Fri Mar 19 03:56:42 2010 From: hitesh.dhiman.1988 at gmail.com (hitesh dhiman) Date: Fri, 19 Mar 2010 10:56:42 +0800 Subject: [C++-sig] Fwd: passing pointers from python In-Reply-To: References: Message-ID: ---------- Forwarded message ---------- From: hitesh dhiman Date: Thu, Mar 18, 2010 at 11:39 AM Subject: passing pointers from python To: Development of Python/C++ integration , boost-users at lists.boost.org Hi all, i'm trying to wrap c++ functions that have pointer variables. The test example i'm using is shown below: int World::addition(int* a, int* b) { int z = *a + *b; return z; } Now, i defined it in my wrapper as : .def("addition", &World::addition) My code compiles, but when I try to execute it from python, i get this error: Python Argument types in World.Addition(World, int, int) did not match C++ signature: addition(class World {lvalue}, int* , int*) Is there a workaround for this?? -- Regards, Hitesh Dhiman Electrical Engineering National University of Singapore -- Regards, Hitesh Dhiman Electrical Engineering National University of Singapore -------------- next part -------------- An HTML attachment was scrubbed... URL: From talljimbo at gmail.com Fri Mar 19 04:22:19 2010 From: talljimbo at gmail.com (Jim Bosch) Date: Thu, 18 Mar 2010 20:22:19 -0700 Subject: [C++-sig] Fwd: passing pointers from python In-Reply-To: References: Message-ID: <1268968939.2269.7.camel@bishop> On Fri, 2010-03-19 at 10:56 +0800, hitesh dhiman wrote: > > > ---------- Forwarded message ---------- > From: hitesh dhiman > Date: Thu, Mar 18, 2010 at 11:39 AM > Subject: passing pointers from python > To: Development of Python/C++ integration , > boost-users at lists.boost.org > > > Hi all, > i'm trying to wrap c++ functions that have pointer variables. The test > example i'm using is shown below: > int World::addition(int* a, int* b) > { > int z = *a + *b; > return z; > } > > > Now, i defined it in my wrapper as : > .def("addition", &World::addition) > > > My code compiles, but when I try to execute it from python, i get this > error: > Python Argument types in World.Addition(World, int, int) did not match > C++ signature: addition(class World {lvalue}, int* , int*) > > > Is there a workaround for this?? > I can't think of an easy one - your C++ function signature implies that it could change the arguments (otherwise, why pass by pointer?), but Python integers are immutable objects, and can't be changed when passed as arguments. That's why Boost.Python isn't doing the conversion automatically. If your code doesn't need to actually modify its arguments - as is the case in your example - you can of course write C++ wrappers that take arguments by value and forward them as pointers, and just wrap those functions for Python. Note that you can wrap a free function that takes a World& as its first argument as a member function of the World class; there will be no difference between that and wrapping a true member function on the Python side. Jim Bosch From hitesh.dhiman.1988 at gmail.com Fri Mar 19 05:59:07 2010 From: hitesh.dhiman.1988 at gmail.com (hitesh dhiman) Date: Fri, 19 Mar 2010 12:59:07 +0800 Subject: [C++-sig] Fwd: passing pointers from python In-Reply-To: <1268968939.2269.7.camel@bishop> References: <1268968939.2269.7.camel@bishop> Message-ID: Hi Jim Thanks...thats what i'm trying to do right now. Will post if any problems occur. On Fri, Mar 19, 2010 at 11:22 AM, Jim Bosch wrote: > On Fri, 2010-03-19 at 10:56 +0800, hitesh dhiman wrote: > > > > > > ---------- Forwarded message ---------- > > From: hitesh dhiman > > Date: Thu, Mar 18, 2010 at 11:39 AM > > Subject: passing pointers from python > > To: Development of Python/C++ integration , > > boost-users at lists.boost.org > > > > > > Hi all, > > i'm trying to wrap c++ functions that have pointer variables. The test > > example i'm using is shown below: > > int World::addition(int* a, int* b) > > { > > int z = *a + *b; > > return z; > > } > > > > > > Now, i defined it in my wrapper as : > > .def("addition", &World::addition) > > > > > > My code compiles, but when I try to execute it from python, i get this > > error: > > Python Argument types in World.Addition(World, int, int) did not match > > C++ signature: addition(class World {lvalue}, int* , int*) > > > > > > Is there a workaround for this?? > > > > I can't think of an easy one - your C++ function signature implies that > it could change the arguments (otherwise, why pass by pointer?), but > Python integers are immutable objects, and can't be changed when passed > as arguments. That's why Boost.Python isn't doing the conversion > automatically. > > If your code doesn't need to actually modify its arguments - as is the > case in your example - you can of course write C++ wrappers that take > arguments by value and forward them as pointers, and just wrap those > functions for Python. Note that you can wrap a free function that takes > a World& as its first argument as a member function of the World class; > there will be no difference between that and wrapping a true member > function on the Python side. > > > Jim Bosch > > > > _______________________________________________ > Cplusplus-sig mailing list > Cplusplus-sig at python.org > http://mail.python.org/mailman/listinfo/cplusplus-sig > -- Regards, Hitesh Dhiman Electrical Engineering National University of Singapore -------------- next part -------------- An HTML attachment was scrubbed... URL: From hitesh.dhiman.1988 at gmail.com Fri Mar 19 07:45:44 2010 From: hitesh.dhiman.1988 at gmail.com (hitesh dhiman) Date: Fri, 19 Mar 2010 14:45:44 +0800 Subject: [C++-sig] vc++ assertion error upon runtime Message-ID: Hi all, I'm trying to gain access to functions that use pointers as arguments. I have written the wrapper file that converts the arguments into pointers. The compilation works successfully, but when i try to run the code from python, it gives an assertion error: Debug Assertion Failed! Expression: Vector subscript out of range Surprisingly, this error only occurs when a particular function is called, Until that point, the code works perfectly. Could someone guide me what to do?? -- Regards, Hitesh Dhiman Electrical Engineering National University of Singapore -------------- next part -------------- An HTML attachment was scrubbed... URL: From talljimbo at gmail.com Fri Mar 19 07:50:39 2010 From: talljimbo at gmail.com (Jim Bosch) Date: Thu, 18 Mar 2010 23:50:39 -0700 Subject: [C++-sig] vc++ assertion error upon runtime In-Reply-To: References: Message-ID: <1268981439.4936.1.camel@bishop> On Fri, 2010-03-19 at 14:45 +0800, hitesh dhiman wrote: > Hi all, > I'm trying to gain access to functions that use pointers as > arguments. I have written the wrapper file that converts the arguments > into pointers. The compilation works successfully, but when i try to > run the code from python, it gives an assertion error: > Debug Assertion Failed! > Expression: Vector subscript out of range > > > Surprisingly, this error only occurs when a particular function is > called, Until that point, the code works perfectly. > > > Could someone guide me what to do?? You'll need to provide some more information. Could you post a simplified version of your code that demonstrates the problem? Jim From macieksitarz at wp.pl Fri Mar 19 17:42:40 2010 From: macieksitarz at wp.pl (Maciej Sitarz) Date: Fri, 19 Mar 2010 17:42:40 +0100 Subject: [C++-sig] Py++ module for code with protected operator= Message-ID: <4BA3A980.4080301@wp.pl> Hi all, I want to create python module for class that has protected operator=. That class placed in std::vector and code generated by Py++ uses that operator. Simple example... ***** The c++ code: #include class JobPropertyWrapper { protected: JobPropertyWrapper& operator=( const JobPropertyWrapper& aProp ) throw () { return *this; } }; class classA { public: void fun( const std::vector& v) { } }; int main() { classA c; c.fun( std::vector() ); return 1; } ****** Py++ script: mb = module_builder.module_builder_t( ... ) mb.class_( 'JobPropertyWrapper' ).noncopyable = True mb.build_code_creator( module_name='test' ) ****** The compile error(part of it): test.h:6: error: 'JobPropertyWrapper& JobPropertyWrapper::operator=(const JobPropertyWrapper&)' is protected /usr/include/boost/python/suite/indexing/vector_indexing_suite.hpp:91: error: within this context test.h: In member function 'void std::vector<_Tp, _Alloc>::_M_insert_aux(__gnu_cxx::__normal_iterator::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> >, const _Tp&) [with _Tp = JobPropertyWrapper, _Alloc = std::allocator]': As you can see i tried to inform py++ that the class is 'noncopyable' but that didn't do the trick. I attached the generated code. There's also some problem with operator== not existing, which I also didn't know how to fix. Thanks in advance -- Maciek Sitarz -- Maciek Sitarz -------------- next part -------------- A non-text attachment was scrubbed... Name: generated_True.cpp Type: text/x-c++src Size: 1434 bytes Desc: not available URL: From rogeeff at gmail.com Fri Mar 19 20:50:44 2010 From: rogeeff at gmail.com (Gennadiy Rozental) Date: Fri, 19 Mar 2010 19:50:44 +0000 (UTC) Subject: [C++-sig] docstring for property? Message-ID: How do I provide doc string to the property like this: ... .add_property( "goo", make_function(...) ) While we are at it, how do I provide docstring and arg names to the operators: ... .def( self < self ) Gennadiy From rogeeff at gmail.com Fri Mar 19 20:55:16 2010 From: rogeeff at gmail.com (Gennadiy Rozental) Date: Fri, 19 Mar 2010 19:55:16 +0000 (UTC) Subject: [C++-sig] boost.pyton scope bug? Message-ID: I am doing something like this in export part of mymodule: scope S = class_("X", no_init ); class_( "Y",... ) ... ; In Python I do see mymodule.X.Y, but mymodule.X.Y.__name__ is 'mymodule.Y' Gennadiy From talljimbo at gmail.com Fri Mar 19 21:37:00 2010 From: talljimbo at gmail.com (Jim Bosch) Date: Fri, 19 Mar 2010 13:37:00 -0700 Subject: [C++-sig] boost.pyton scope bug? In-Reply-To: References: Message-ID: <1269031020.3609.9.camel@mu> On Fri, 2010-03-19 at 19:55 +0000, Gennadiy Rozental wrote: > I am doing something like this in export part of mymodule: > > scope S = class_("X", no_init ); > > class_( "Y",... ) > ... > ; > > In Python I do see mymodule.X.Y, but mymodule.X.Y.__name__ is 'mymodule.Y' > Hmm. In the same situation, I simply get mymodule.X.Y.__name__ == 'Y' (and mymodule.X.__name__ == 'X') - no module prefixes at all. That matches the pure-python inner class result, at least on my system. I do get mymodule.X.__module__ == 'mymodule' and mymodule.X.Y.__module__ == 'mymodule', but that's also correct as far as mirroring the pure-python inner class result. (This is Python 2.6.4; it may have changed in 3.0, but I certainly hope it doesn't depend on anything else). Note that you can change the __module__ attribute; I often import my wrapped names into different submodules in a package and adjust their __module__ accordingly to make a Python interface that mirrors the C++ namespaces better - but all that has to be done in Python; boost python can't do it for you (maybe Py++ could?) Jim Bosch From rogeeff at gmail.com Fri Mar 19 22:44:55 2010 From: rogeeff at gmail.com (Gennadiy Rozental) Date: Fri, 19 Mar 2010 21:44:55 +0000 (UTC) Subject: [C++-sig] boost.pyton scope bug? References: <1269031020.3609.9.camel@mu> Message-ID: Jim Bosch gmail.com> writes: > > On Fri, 2010-03-19 at 19:55 +0000, Gennadiy Rozental wrote: > > I am doing something like this in export part of mymodule: > > > > scope S = class_("X", no_init ); > > > > class_( "Y",... ) > > ... > > ; > > > > In Python I do see mymodule.X.Y, but mymodule.X.Y.__name__ is 'mymodule.Y' > > > > Hmm. In the same situation, I simply get mymodule.X.Y.__name__ == > 'Y' (and mymodule.X.__name__ == 'X') - no module prefixes at all. That > matches the pure-python inner class result, at least on my system. You right. I got it wrong when reported the error. The problem, is that when I print mymodule.X.Y I am getting which is wrong IMO > I do get mymodule.X.__module__ == 'mymodule' and mymodule.X.Y.__module__ > == 'mymodule', but that's also correct as far as mirroring the > pure-python inner class result. Well I hoped to mimic some kind of subnamespace with scope. Thus the module should be mymodule.X or the name should be X.Y > Note that you can change the __module__ attribute; I often import my > wrapped names into different submodules in a package and adjust their > __module__ accordingly to make a Python interface that mirrors the C++ > namespaces better - but all that has to be done in Python; boost python > can't do it for you (maybe Py++ could?) Can you show an example? I am currently tweaking this Python as well (post loading) like this: mymodule.X.Y.__name__ = 'X.Y' It's still not completely satisfactory, since help(mymodule.X) does not do the right job, but at least it does not show Y as 'mymodule.Y' Gennadiy From rogeeff at gmail.com Fri Mar 19 22:56:32 2010 From: rogeeff at gmail.com (Gennadiy Rozental) Date: Fri, 19 Mar 2010 21:56:32 +0000 (UTC) Subject: [C++-sig] how to avoid documenting private methods Message-ID: I've got exported class A and I'd like to avoid reporting private methods when users type help (mymodule.A). Is there anything like __all__ for modules? naming these methods starting with _ does not help either. Please advise, Gennadiy From roman.yakovenko at gmail.com Sat Mar 20 19:12:30 2010 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Sat, 20 Mar 2010 20:12:30 +0200 Subject: [C++-sig] Py++ module for code with protected operator= In-Reply-To: <4BA3A980.4080301@wp.pl> References: <4BA3A980.4080301@wp.pl> Message-ID: <7465b6171003201112k5a39e066k7a3f59007b63aea1@mail.gmail.com> On Fri, Mar 19, 2010 at 6:42 PM, Maciej Sitarz wrote: > > Hi all, > > I want to create python module for class that has protected operator=. > That class placed in std::vector and code generated by Py++ uses that operator. I could be wring, but if I remember right, you can not use such classes with Boost.Python indexing suite. I suggest you to switch to the indexing suite that comes with Py++: http://language-binding.net/pyplusplus/documentation/containers.html . I am pretty sure it will work out of the box. You will not have to specify "noncopyable=True". HTH -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From roman.yakovenko at gmail.com Sat Mar 20 19:17:05 2010 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Sat, 20 Mar 2010 20:17:05 +0200 Subject: [C++-sig] Py++ - one header file including all project header files In-Reply-To: <4BA2B6F6.1060307@wp.pl> References: <4BA0870B.9090605@wp.pl> <7465b6171003170052j7b89313at5a6901445f33c096@mail.gmail.com> <4BA2B6F6.1060307@wp.pl> Message-ID: <7465b6171003201117n231a21deofdd5c4f7db6303d2@mail.gmail.com> On Fri, Mar 19, 2010 at 1:27 AM, Maciej Sitarz wrote: > On 17.03.2010 08:52, Roman Yakovenko wrote: >> >> Nothing, really. >> >> Please take a look on the following document: >> >> http://language-binding.net/pyplusplus/documentation/tutorials/module_builder/module_builder.html#declarations-customization >> and let me know whether is makes sense to you. >> >> If not come back and we will resolve the issue > > Thanks, I added this two loops for ex/including some classes and now it > works as it should. > > # Include Cream CE classes > for class_name in environment.include_classes: > ? ? ? ?print "Including class '%s'" % class_name > ? ? ? ?mb.class_( name=class_name ).include() > > # Exclude Cream CE classes > for class_name in environment.exclude_classes: > ? ? ? ?print "Excluding class '%s'" % class_name > ? ? ? ?mb.class_( name=class_name ).exclude() You can write it shorter: mb._classes( lambda cls: cls.name in environment.exclude_classes ).exclude() :-) -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From macieksitarz at wp.pl Sat Mar 20 20:15:26 2010 From: macieksitarz at wp.pl (Maciej Sitarz) Date: Sat, 20 Mar 2010 20:15:26 +0100 Subject: [C++-sig] Py++ module for code with protected operator= In-Reply-To: <7465b6171003201112k5a39e066k7a3f59007b63aea1@mail.gmail.com> References: <4BA3A980.4080301@wp.pl> <7465b6171003201112k5a39e066k7a3f59007b63aea1@mail.gmail.com> Message-ID: <4BA51ECE.3040501@wp.pl> On 20.03.2010 19:12, Roman Yakovenko wrote: > On Fri, Mar 19, 2010 at 6:42 PM, Maciej Sitarz wrote: >> >> Hi all, >> >> I want to create python module for class that has protected operator=. >> That class placed in std::vector and code generated by Py++ uses that operator. > > I could be wring, but if I remember right, you can not use such > classes with Boost.Python indexing suite. I suggest you to switch to > the indexing suite that comes with Py++: > http://language-binding.net/pyplusplus/documentation/containers.html . > I am pretty sure it will work out of the box. You will not have to > specify "noncopyable=True". I tried indexing_suite_version=2 but the problem is still the same. Difference in generated code with noncopyable set and not set: --- generated_idx2.cpp 2010-03-20 19:58:42.611632788 +0100 +++ generated_idx2_noncopyable.cpp 2010-03-20 20:00:39.494986097 +0100 @@ -40,7 +40,7 @@ BOOST_PYTHON_MODULE(test){ vector_less__JobPropertyWrapper__greater__exposer.def( bp::indexing::vector_suite< std::vector< JobPropertyWrapper > >() ); } - bp::class_< JobPropertyWrapper >( "JobPropertyWrapper" ); + bp::class_< JobPropertyWrapper, boost::noncopyable >( "JobPropertyWrapper" ); The compile errors are still the same: generated.cpp:40: instantiated from here test.h:6: error: 'JobPropertyWrapper& JobPropertyWrapper::operator=(const JobPropertyWrapper&)' is protected I attached the generated file with this mail. -- Maciek Sitarz -------------- next part -------------- A non-text attachment was scrubbed... Name: generated.cpp Type: text/x-c++src Size: 1790 bytes Desc: not available URL: From roman.yakovenko at gmail.com Sat Mar 20 20:47:24 2010 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Sat, 20 Mar 2010 21:47:24 +0200 Subject: [C++-sig] Py++ module for code with protected operator= In-Reply-To: <4BA51ECE.3040501@wp.pl> References: <4BA3A980.4080301@wp.pl> <7465b6171003201112k5a39e066k7a3f59007b63aea1@mail.gmail.com> <4BA51ECE.3040501@wp.pl> Message-ID: <7465b6171003201247g4490dbacgb349e0fec4270406@mail.gmail.com> On Sat, Mar 20, 2010 at 9:15 PM, Maciej Sitarz wrote: > On 20.03.2010 19:12, Roman Yakovenko wrote: >> >> On Fri, Mar 19, 2010 at 6:42 PM, Maciej Sitarz ?wrote: > The compile errors are still the same: > generated.cpp:40: ? instantiated from here > test.h:6: error: 'JobPropertyWrapper& JobPropertyWrapper::operator=(const > JobPropertyWrapper&)' is protected > Sorry, I missed the point in the initial post. The error has nothing to do with generated code. You can define class with protected operator=, but you will not be able to insert it into std::vector, because it requires public operator= . I think, you will have to change your code. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From macieksitarz at wp.pl Sat Mar 20 21:12:05 2010 From: macieksitarz at wp.pl (Maciej Sitarz) Date: Sat, 20 Mar 2010 21:12:05 +0100 Subject: [C++-sig] Py++ module for code with protected operator= In-Reply-To: <7465b6171003201247g4490dbacgb349e0fec4270406@mail.gmail.com> References: <4BA3A980.4080301@wp.pl> <7465b6171003201112k5a39e066k7a3f59007b63aea1@mail.gmail.com> <4BA51ECE.3040501@wp.pl> <7465b6171003201247g4490dbacgb349e0fec4270406@mail.gmail.com> Message-ID: <4BA52C15.8060107@wp.pl> On 20.03.2010 20:47, Roman Yakovenko wrote: > On Sat, Mar 20, 2010 at 9:15 PM, Maciej Sitarz wrote: >> On 20.03.2010 19:12, Roman Yakovenko wrote: >>> >>> On Fri, Mar 19, 2010 at 6:42 PM, Maciej Sitarz wrote: >> The compile errors are still the same: >> generated.cpp:40: instantiated from here >> test.h:6: error: 'JobPropertyWrapper& JobPropertyWrapper::operator=(const >> JobPropertyWrapper&)' is protected >> > > Sorry, I missed the point in the initial post. The error has nothing > to do with generated code. You can define class with protected > operator=, but you will not be able to insert it into std::vector, > because it requires public operator= . Em... but the example main() compiles and works... unless I want to 'push_back' object to the vector. > I think, you will have to change your code. I could change it in the example, but I can't change the code for which I'm making the python module. I think I should investigate how the vector is created and put into the function in the original project. Or maybe you have other suggestions? -- Maciek Sitarz From roman.yakovenko at gmail.com Sat Mar 20 21:24:11 2010 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Sat, 20 Mar 2010 22:24:11 +0200 Subject: [C++-sig] Py++ module for code with protected operator= In-Reply-To: <4BA52C15.8060107@wp.pl> References: <4BA3A980.4080301@wp.pl> <7465b6171003201112k5a39e066k7a3f59007b63aea1@mail.gmail.com> <4BA51ECE.3040501@wp.pl> <7465b6171003201247g4490dbacgb349e0fec4270406@mail.gmail.com> <4BA52C15.8060107@wp.pl> Message-ID: <7465b6171003201324s6fd8a949lc17e5b6b9342fd71@mail.gmail.com> On Sat, Mar 20, 2010 at 10:12 PM, Maciej Sitarz wrote: > On 20.03.2010 20:47, Roman Yakovenko wrote: > Em... but the example main() compiles and works... unless I want to > 'push_back' object to the vector. This is exactly my point >> I think, you will have to change your code. > > I could change it in the example, but I can't change the code for which I'm > making the python module. > I think I should investigate how the vector is created and put into the > function in the original project. > Or maybe you have other suggestions? Yes. Can you show/point me to the original code you are trying to expose. ( not the whole library but the concrete class ). -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From peoro.noob at gmail.com Sat Mar 20 21:31:22 2010 From: peoro.noob at gmail.com (peoro) Date: Sat, 20 Mar 2010 21:31:22 +0100 Subject: [C++-sig] [Py++] boost::shared_ptr casting Message-ID: <1c7ed23c1003201331o1d00fccr5d7e4a71478eaaf2@mail.gmail.com> Hello, I'm having some issues with shared_ptr's in a Python environment: it looks like once a shared_ptr enters Python, it cannot be upcasted nor downcasted. Here's a brief C++ source code to explain better the issue: #include class Base { }; class Derived : public Base { }; boost::shared_ptr base1( ) { return boost::shared_ptr( new Base ); } boost::shared_ptr base2( ) { return boost::shared_ptr( new Derived ); } boost::shared_ptr base3( boost::shared_ptr derived ) { return boost::shared_ptr( derived ); } boost::shared_ptr derived1( ) { return boost::shared_ptr( new Derived ); } boost::shared_ptr derived2( boost::shared_ptr base ) { return boost::static_pointer_cast( base ); } then, after building the library and importing it into Python, I would expect something like this: from shared_ptr_inheritance import * type( base1() ) -> Base type( base2() ) -> Base type( derived1() ) -> Derived type( base3( derived1() ) ) -> Base type( derived2( base2() ) ) -> Derived but instead, this is the actual behaviour: from shared_ptr_inheritance import * type( base1() ) -> Base type( base2() ) -> Base type( derived1() ) -> Derived type( base3( derived1() ) ) -> Derived (!!!) type( derived2( base2() ) ) -> Base (!!!) am I doing something wrong? why does this happen, and, mostly, how can I cast a shared_ptr containing a Derived pointer, to shared_ptr ? From macieksitarz at wp.pl Sat Mar 20 21:46:33 2010 From: macieksitarz at wp.pl (Maciej Sitarz) Date: Sat, 20 Mar 2010 21:46:33 +0100 Subject: [C++-sig] Py++ module for code with protected operator= In-Reply-To: <7465b6171003201324s6fd8a949lc17e5b6b9342fd71@mail.gmail.com> References: <4BA3A980.4080301@wp.pl> <7465b6171003201112k5a39e066k7a3f59007b63aea1@mail.gmail.com> <4BA51ECE.3040501@wp.pl> <7465b6171003201247g4490dbacgb349e0fec4270406@mail.gmail.com> <4BA52C15.8060107@wp.pl> <7465b6171003201324s6fd8a949lc17e5b6b9342fd71@mail.gmail.com> Message-ID: <4BA53429.2070306@wp.pl> On 20.03.2010 21:24, Roman Yakovenko wrote: > On Sat, Mar 20, 2010 at 10:12 PM, Maciej Sitarz wrote: >> On 20.03.2010 20:47, Roman Yakovenko wrote: >>> I think, you will have to change your code. >> >> I could change it in the example, but I can't change the code for which I'm >> making the python module. >> I think I should investigate how the vector is created and put into the >> function in the original project. >> Or maybe you have other suggestions? > > Yes. Can you show/point me to the original code you are trying to > expose. ( not the whole library but the concrete class ). Class constructor in line *72* accepts vector : http://freya.dsv.agh.edu.pl/~macieks/pycream/cream-client-api-c/JobIdWrapper.h And the JobPropertyWrapper is here: http://freya.dsv.agh.edu.pl/~macieks/pycream//cream-client-api-c/JobPropertyWrapper.h -- Maciek Sitarz From talljimbo at gmail.com Sat Mar 20 22:06:42 2010 From: talljimbo at gmail.com (Jim Bosch) Date: Sat, 20 Mar 2010 14:06:42 -0700 Subject: [C++-sig] [Py++] boost::shared_ptr casting In-Reply-To: <1c7ed23c1003201331o1d00fccr5d7e4a71478eaaf2@mail.gmail.com> References: <1c7ed23c1003201331o1d00fccr5d7e4a71478eaaf2@mail.gmail.com> Message-ID: <1269119202.2301.3.camel@bishop> On Sat, 2010-03-20 at 21:31 +0100, peoro wrote: > Hello, > > I'm having some issues with shared_ptr's in a Python environment: it > looks like once a shared_ptr enters Python, it cannot be upcasted nor > downcasted. > > Here's a brief C++ source code to explain better the issue: > > > #include > > class Base { }; > class Derived : public Base { }; > > boost::shared_ptr base1( ) { > return boost::shared_ptr( new Base ); > } > boost::shared_ptr base2( ) { > return boost::shared_ptr( new Derived ); > } > boost::shared_ptr base3( boost::shared_ptr derived ) { > return boost::shared_ptr( derived ); > } > boost::shared_ptr derived1( ) { > return boost::shared_ptr( new Derived ); > } > boost::shared_ptr derived2( boost::shared_ptr base ) { > return boost::static_pointer_cast( base ); > } > > > then, after building the library and importing it into Python, I would > expect something like this: > > > from shared_ptr_inheritance import * > type( base1() ) -> Base > type( base2() ) -> Base > type( derived1() ) -> Derived > type( base3( derived1() ) ) -> Base > type( derived2( base2() ) ) -> Derived > > > but instead, this is the actual behaviour: > > > from shared_ptr_inheritance import * > type( base1() ) -> Base > type( base2() ) -> Base > type( derived1() ) -> Derived > type( base3( derived1() ) ) -> Derived (!!!) > type( derived2( base2() ) ) -> Base (!!!) > > > am I doing something wrong? > why does this happen, and, mostly, how can I cast a shared_ptr > containing a Derived pointer, to shared_ptr ? > ______________________________________________ If you've wrapped all classes with shared_ptr storage, to-python converts should always produce the most-derived type in Python, and I think that's what you want on the Python side. This may not work if you can't use shared_ptr storage for some reason, or if you return an intermediate class you haven't wrapped. Are you using shared_ptr storage? Jim Bosch From macieksitarz at wp.pl Sat Mar 20 22:10:08 2010 From: macieksitarz at wp.pl (Maciej Sitarz) Date: Sat, 20 Mar 2010 22:10:08 +0100 Subject: [C++-sig] Py++ module for code with protected operator= In-Reply-To: <4BA53429.2070306@wp.pl> References: <4BA3A980.4080301@wp.pl> <7465b6171003201112k5a39e066k7a3f59007b63aea1@mail.gmail.com> <4BA51ECE.3040501@wp.pl> <7465b6171003201247g4490dbacgb349e0fec4270406@mail.gmail.com> <4BA52C15.8060107@wp.pl> <7465b6171003201324s6fd8a949lc17e5b6b9342fd71@mail.gmail.com> <4BA53429.2070306@wp.pl> Message-ID: <4BA539B0.5040208@wp.pl> Just one more comment... The constructor takes reference to vector, so I suspect that maybe it will be filled there by some other code I don't have? So I don't need to fill the vector, just to create it (I will ask the developers) Additional source + documentation (but no details ): http://grid.pd.infn.it/cream/CppApiDoc/JobIdWrapper_8h-source.html http://grid.pd.infn.it/cream/CppApiDoc/JobPropertyWrapper_8h-source.html -- Maciek Sitarz From skip at pobox.com Sun Mar 21 02:01:22 2010 From: skip at pobox.com (Skip Montanaro) Date: Sun, 21 Mar 2010 01:01:22 +0000 (UTC) Subject: [C++-sig] Boost.Python and PEP 384 Message-ID: Do Boost.Python-generated extension modules conform to PEP 384's constraints for ABI compatibility? Thx, Skip Montanaro From peoro.noob at gmail.com Sun Mar 21 03:07:28 2010 From: peoro.noob at gmail.com (peoro) Date: Sun, 21 Mar 2010 03:07:28 +0100 Subject: [C++-sig] [Py++] boost::shared_ptr casting In-Reply-To: <1269119202.2301.3.camel@bishop> References: <1c7ed23c1003201331o1d00fccr5d7e4a71478eaaf2@mail.gmail.com> <1269119202.2301.3.camel@bishop> Message-ID: <1c7ed23c1003201907v44fccad9gc23c02eb36c631f@mail.gmail.com> Yes, having all of the objects at their most-derived type would be what I need, but it's not what happens. I posted a piece of C++ code that shows what I do (I exported it using py++ without any further modification): all of the pointers my functions return are wrapped in boost::shared_ptr's, but from Python I see them at the "derivation level" they were when I passed them to python the first time (look at the summarized output in my previous message)... On Sat, Mar 20, 2010 at 10:06 PM, Jim Bosch wrote: > On Sat, 2010-03-20 at 21:31 +0100, peoro wrote: >> Hello, >> >> I'm having some issues with shared_ptr's in a Python environment: it >> looks like once a shared_ptr enters Python, it cannot be upcasted nor >> downcasted. >> >> Here's a brief C++ source code to explain better the issue: >> >> >> #include >> >> class Base { }; >> class Derived : public Base { }; >> >> boost::shared_ptr base1( ) { >> ? return boost::shared_ptr( new Base ); >> } >> boost::shared_ptr base2( ) { >> ? return boost::shared_ptr( new Derived ); >> } >> boost::shared_ptr base3( boost::shared_ptr derived ) { >> ? return boost::shared_ptr( derived ); >> } >> boost::shared_ptr derived1( ) { >> ? return boost::shared_ptr( new Derived ); >> } >> boost::shared_ptr derived2( boost::shared_ptr base ) { >> ? return boost::static_pointer_cast( base ); >> } >> >> >> then, after building the library and importing it into Python, I would >> expect something like this: >> >> >> from shared_ptr_inheritance import * >> type( base1() ) -> Base >> type( base2() ) -> Base >> type( derived1() ) -> Derived >> type( base3( derived1() ) ) -> Base >> type( derived2( base2() ) ) -> Derived >> >> >> but instead, this is the actual behaviour: >> >> >> from shared_ptr_inheritance import * >> type( base1() ) -> Base >> type( base2() ) -> Base >> type( derived1() ) -> Derived >> type( base3( derived1() ) ) -> Derived (!!!) >> type( derived2( base2() ) ) -> Base (!!!) >> >> >> am I doing something wrong? >> why does this happen, and, mostly, how can I cast a shared_ptr >> containing a Derived pointer, to shared_ptr ? >> ______________________________________________ > > If you've wrapped all classes with shared_ptr storage, to-python > converts should always produce the most-derived type in Python, and I > think that's what you want on the Python side. ?This may not work if you > can't use shared_ptr storage for some reason, or if you return an > intermediate class you haven't wrapped. > > Are you using shared_ptr storage? > > > Jim Bosch > > _______________________________________________ > Cplusplus-sig mailing list > Cplusplus-sig at python.org > http://mail.python.org/mailman/listinfo/cplusplus-sig > From roman.yakovenko at gmail.com Sun Mar 21 06:07:19 2010 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Sun, 21 Mar 2010 07:07:19 +0200 Subject: [C++-sig] Py++ module for code with protected operator= In-Reply-To: <4BA539B0.5040208@wp.pl> References: <4BA3A980.4080301@wp.pl> <7465b6171003201112k5a39e066k7a3f59007b63aea1@mail.gmail.com> <4BA51ECE.3040501@wp.pl> <7465b6171003201247g4490dbacgb349e0fec4270406@mail.gmail.com> <4BA52C15.8060107@wp.pl> <7465b6171003201324s6fd8a949lc17e5b6b9342fd71@mail.gmail.com> <4BA53429.2070306@wp.pl> <4BA539B0.5040208@wp.pl> Message-ID: <7465b6171003202207h5c2816e5jf75383464d0e7beb@mail.gmail.com> On Sat, Mar 20, 2010 at 11:10 PM, Maciej Sitarz wrote: > Just one more comment... > > The constructor takes reference to vector, so I suspect > that maybe it will be filled there by some other code I don't have? So I > don't need to fill the vector, just to create it (I will ask the developers) Right, you'd better talk with them. Boost.Python allows to export libraries without touching them, but sometimes a small library change could make you task easier. The following code works: #include struct item_t{ explicit item_t( int v) : value( v ) {} int value; protected: item_t& operator=( const item_t& other ); }; int main( int argc, const char** argv ){ std::vector< item_t > values( 10, item_t( 12 )); for( size_t i = 0; i < values.size(); ++i ){ values[ i ].value = i; } } -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From talljimbo at gmail.com Sun Mar 21 06:07:16 2010 From: talljimbo at gmail.com (Jim Bosch) Date: Sat, 20 Mar 2010 22:07:16 -0700 Subject: [C++-sig] [Py++] boost::shared_ptr casting In-Reply-To: <1c7ed23c1003201907v44fccad9gc23c02eb36c631f@mail.gmail.com> References: <1c7ed23c1003201331o1d00fccr5d7e4a71478eaaf2@mail.gmail.com> <1269119202.2301.3.camel@bishop> <1c7ed23c1003201907v44fccad9gc23c02eb36c631f@mail.gmail.com> Message-ID: <1269148036.4792.3.camel@bishop> On Sun, 2010-03-21 at 03:07 +0100, peoro wrote: > Yes, having all of the objects at their most-derived type would be > what I need, but it's not what happens. > > I posted a piece of C++ code that shows what I do (I exported it using > py++ without any further modification): all of the pointers my > functions return are wrapped in boost::shared_ptr's, but from Python I > see them at the "derivation level" they were when I passed them to > python the first time (look at the summarized output in my previous > message)... > Ok, maybe I'm not familiar with Py++ enough to help - I tend to just use Boost.Python directly. What I meant by "shared_ptr storage" is whether your class wrapper declarations look like this: boost::python::class_< wrapped, boost::shared_ptr > or this: boost::python::class_< wrapped > If it's the former, the downcasting will happen automatically. I would guess Py++ has a switch that turns this on, but I don't know what it is. Jim From roman.yakovenko at gmail.com Sun Mar 21 06:11:14 2010 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Sun, 21 Mar 2010 07:11:14 +0200 Subject: [C++-sig] [Py++] boost::shared_ptr casting In-Reply-To: <1c7ed23c1003201907v44fccad9gc23c02eb36c631f@mail.gmail.com> References: <1c7ed23c1003201331o1d00fccr5d7e4a71478eaaf2@mail.gmail.com> <1269119202.2301.3.camel@bishop> <1c7ed23c1003201907v44fccad9gc23c02eb36c631f@mail.gmail.com> Message-ID: <7465b6171003202211p2595918ai3be07419c65c3b96@mail.gmail.com> On Sun, Mar 21, 2010 at 4:07 AM, peoro wrote: > Yes, having all of the objects at their most-derived type would be > what I need, but it's not what happens. > > I posted a piece of C++ code that shows what I do (I exported it using > py++ without any further modification): all of the pointers my > functions return are wrapped in boost::shared_ptr's, but from Python I > see them at the "derivation level" they were when I passed them to > python the first time (look at the summarized output in my previous > message)... Can you check your code, but with the following class definition class Base { public: virtual ~Base(){} }; class Derived : public Base { }; -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From macieksitarz at wp.pl Sun Mar 21 09:06:59 2010 From: macieksitarz at wp.pl (Maciej Sitarz) Date: Sun, 21 Mar 2010 09:06:59 +0100 Subject: [C++-sig] Py++ module for code with protected operator= In-Reply-To: <7465b6171003202207h5c2816e5jf75383464d0e7beb@mail.gmail.com> References: <4BA3A980.4080301@wp.pl> <7465b6171003201112k5a39e066k7a3f59007b63aea1@mail.gmail.com> <4BA51ECE.3040501@wp.pl> <7465b6171003201247g4490dbacgb349e0fec4270406@mail.gmail.com> <4BA52C15.8060107@wp.pl> <7465b6171003201324s6fd8a949lc17e5b6b9342fd71@mail.gmail.com> <4BA53429.2070306@wp.pl> <4BA539B0.5040208@wp.pl> <7465b6171003202207h5c2816e5jf75383464d0e7beb@mail.gmail.com> Message-ID: <4BA5D3A3.9030309@wp.pl> On 21.03.2010 06:07, Roman Yakovenko wrote: > On Sat, Mar 20, 2010 at 11:10 PM, Maciej Sitarz wrote: >> Just one more comment... >> >> The constructor takes reference to vector, so I suspect >> that maybe it will be filled there by some other code I don't have? So I >> don't need to fill the vector, just to create it (I will ask the developers) > > Right, you'd better talk with them. Boost.Python allows to export > libraries without touching them, but sometimes a small library change > could make you task easier. Yes, it works, because there's no code generated for std::vector Try adding this function to item_t class: void fund( std::vector& v) { } And then it doesn't compile successfully. When I comment this line from the generated code: vector_less__item_t__greater__exposer.def( bp::indexing::vector_suite< std::vector< item_t > >() ); it compiles and appears to work, but I can't figure out how to pass a list/vector to that function: import test item = test.item_t( 10 ) vect = [test.item_t(1), test.item_t(2)] item.fund(vect) --------------------------------------------------------------------------- ArgumentError Traceback (most recent call last) /home/macieks/error_examples/protected_assign/ ArgumentError: Python argument types in item_t.fund(item_t, list) did not match C++ signature: fund(item_t {lvalue}, std::vector > {lvalue} v) In [5]: vect Out[5]: [, ] In [6]: vect? Type: list Base Class: String Form: [, ] Namespace: Interactive Length: 2 Docstring: list() -> new list list(sequence) -> new list initialized from sequence's items I'm not sure, but that should work, shouldn't it? -- Maciek Sitarz From roman.yakovenko at gmail.com Sun Mar 21 09:14:54 2010 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Sun, 21 Mar 2010 10:14:54 +0200 Subject: [C++-sig] Py++ module for code with protected operator= In-Reply-To: <4BA5D3A3.9030309@wp.pl> References: <4BA3A980.4080301@wp.pl> <7465b6171003201112k5a39e066k7a3f59007b63aea1@mail.gmail.com> <4BA51ECE.3040501@wp.pl> <7465b6171003201247g4490dbacgb349e0fec4270406@mail.gmail.com> <4BA52C15.8060107@wp.pl> <7465b6171003201324s6fd8a949lc17e5b6b9342fd71@mail.gmail.com> <4BA53429.2070306@wp.pl> <4BA539B0.5040208@wp.pl> <7465b6171003202207h5c2816e5jf75383464d0e7beb@mail.gmail.com> <4BA5D3A3.9030309@wp.pl> Message-ID: <7465b6171003210114o7eebe0f0j3e03e8304d1ea36@mail.gmail.com> On Sun, Mar 21, 2010 at 10:06 AM, Maciej Sitarz wrote: > Yes, it works, because there's no code generated for std::vector > Try adding this function to item_t class: > void fund( std::vector& v) { } > > And then it doesn't compile successfully. > > When I comment this line from the generated code: > vector_less__item_t__greater__exposer.def( bp::indexing::vector_suite< > std::vector< item_t > >() ); > it compiles and appears to work, but I can't figure out how to pass a > list/vector to that function: > > > import test > item = test.item_t( 10 ) > vect = [test.item_t(1), test.item_t(2)] > item.fund(vect) > --------------------------------------------------------------------------- > ArgumentError ? ? ? ? ? ? ? ? ? ? ? ? ? ? Traceback (most recent call last) > > /home/macieks/error_examples/protected_assign/ > > ArgumentError: Python argument types in > ? ?item_t.fund(item_t, list) > did not match C++ signature: > ? ?fund(item_t {lvalue}, std::vector > > {lvalue} v) > > In [5]: vect > Out[5]: > [, > ?] > > In [6]: vect? > Type: ? ? ? ? ? list > Base Class: ? ? > String Form: ? ?[, at 0x7f8f38899d60>] > Namespace: ? ? ?Interactive > Length: ? ? ? ? 2 > Docstring: > ? ?list() -> new list > ? ?list(sequence) -> new list initialized from sequence's items > > I'm not sure, but that should work, shouldn't it? 1. I would talk with developers to understand the reasons for such interface 2. create wrapper function, which takes regular python list and creates a vector from it and expose this function, instead of the original one -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From peoro.noob at gmail.com Sun Mar 21 15:12:49 2010 From: peoro.noob at gmail.com (peoro) Date: Sun, 21 Mar 2010 15:12:49 +0100 Subject: [C++-sig] [Py++] boost::shared_ptr casting In-Reply-To: <7465b6171003202211p2595918ai3be07419c65c3b96@mail.gmail.com> References: <1c7ed23c1003201331o1d00fccr5d7e4a71478eaaf2@mail.gmail.com> <1269119202.2301.3.camel@bishop> <1c7ed23c1003201907v44fccad9gc23c02eb36c631f@mail.gmail.com> <7465b6171003202211p2595918ai3be07419c65c3b96@mail.gmail.com> Message-ID: <1c7ed23c1003210712t9b5b520w7440bc20386ff24a@mail.gmail.com> Ok, it does work as expected if class Base has got at least one virtual member: from shared_ptr_inheritance import * type( base1() ) -> Base type( base2() ) -> Derived type( derived1() ) -> Derived type( base3( derived1() ) ) -> Derived type( derived2( base2() ) ) -> Derived Anyhow it looks like this doesn't depend on py++: py++ always generates the same boost::python code no matter of destructor's virtuality. ...What if I cannot add a virtual function to the class Base? On Sun, Mar 21, 2010 at 6:11 AM, Roman Yakovenko wrote: > On Sun, Mar 21, 2010 at 4:07 AM, peoro wrote: >> Yes, having all of the objects at their most-derived type would be >> what I need, but it's not what happens. >> >> I posted a piece of C++ code that shows what I do (I exported it using >> py++ without any further modification): all of the pointers my >> functions return are wrapped in boost::shared_ptr's, but from Python I >> see them at the "derivation level" they were when I passed them to >> python the first time (look at the summarized output in my previous >> message)... > > Can you check your code, but with the following class definition > > class Base { > public: > ? ?virtual ~Base(){} > }; > > class Derived : public Base { }; > > > -- > Roman Yakovenko > C++ Python language binding > http://www.language-binding.net/ > _______________________________________________ > Cplusplus-sig mailing list > Cplusplus-sig at python.org > http://mail.python.org/mailman/listinfo/cplusplus-sig > From roman.yakovenko at gmail.com Sun Mar 21 17:02:27 2010 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Sun, 21 Mar 2010 18:02:27 +0200 Subject: [C++-sig] [Py++] boost::shared_ptr casting In-Reply-To: <1c7ed23c1003210712t9b5b520w7440bc20386ff24a@mail.gmail.com> References: <1c7ed23c1003201331o1d00fccr5d7e4a71478eaaf2@mail.gmail.com> <1269119202.2301.3.camel@bishop> <1c7ed23c1003201907v44fccad9gc23c02eb36c631f@mail.gmail.com> <7465b6171003202211p2595918ai3be07419c65c3b96@mail.gmail.com> <1c7ed23c1003210712t9b5b520w7440bc20386ff24a@mail.gmail.com> Message-ID: <7465b6171003210902x6406432el1d189bb27cff8036@mail.gmail.com> On Sun, Mar 21, 2010 at 4:12 PM, peoro wrote: > Ok, it does work as expected if class Base has got at least one virtual member: > > from shared_ptr_inheritance import * > type( base1() ) -> Base > type( base2() ) -> Derived > type( derived1() ) -> Derived > type( base3( derived1() ) ) -> Derived > type( derived2( base2() ) ) -> Derived > > Anyhow it looks like this doesn't depend on py++: py++ always > generates the same boost::python code no matter of destructor's > virtuality. You are right, Py++ assumes that if you have class hierarchy than you follow simple rules ( at least virtual destructor ). > ...What if I cannot add a virtual function to the class Base? As for me, you should not use/expose such code :-) . More seriously, you will have to show a small and complete example of what you are trying to expose. In any case, without virtual table you can't expect the "desired functionality" to work. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From nat at lindenlab.com Sun Mar 21 22:28:05 2010 From: nat at lindenlab.com (Nat Goodspeed) Date: Sun, 21 Mar 2010 17:28:05 -0400 Subject: [C++-sig] [Py++] boost::shared_ptr casting In-Reply-To: <1c7ed23c1003210712t9b5b520w7440bc20386ff24a@mail.gmail.com> References: <1c7ed23c1003201331o1d00fccr5d7e4a71478eaaf2@mail.gmail.com> <1269119202.2301.3.camel@bishop> <1c7ed23c1003201907v44fccad9gc23c02eb36c631f@mail.gmail.com> <7465b6171003202211p2595918ai3be07419c65c3b96@mail.gmail.com> <1c7ed23c1003210712t9b5b520w7440bc20386ff24a@mail.gmail.com> Message-ID: <4BA68F65.5030305@lindenlab.com> peoro wrote: > Ok, it does work as expected if class Base has got at least one virtual member: > > ...What if I cannot add a virtual function to the class Base? If your C++ base class has no virtual methods, even pure C++ can't dynamic_cast<> it. Put differently -- you've been asking Python to determine the runtime type of a class for which C++ maintains no runtime type. It's the presence of at least one virtual method that forces C++ to start tracking the runtime type of a class hierarchy. From peoro.noob at gmail.com Sun Mar 21 23:51:55 2010 From: peoro.noob at gmail.com (peoro) Date: Sun, 21 Mar 2010 23:51:55 +0100 Subject: [C++-sig] [Py++] boost::shared_ptr casting In-Reply-To: <4BA68F65.5030305@lindenlab.com> References: <1c7ed23c1003201331o1d00fccr5d7e4a71478eaaf2@mail.gmail.com> <1269119202.2301.3.camel@bishop> <1c7ed23c1003201907v44fccad9gc23c02eb36c631f@mail.gmail.com> <7465b6171003202211p2595918ai3be07419c65c3b96@mail.gmail.com> <1c7ed23c1003210712t9b5b520w7440bc20386ff24a@mail.gmail.com> <4BA68F65.5030305@lindenlab.com> Message-ID: <1c7ed23c1003211551o691a8e97o3e0532aeac225586@mail.gmail.com> The code I'm trying to wrap doesn't rely on RTTI, that's why there are no virtual functions. (I agree that RTTI would be better from about any point of view, but this piece of software isn't using it) There should be no need of dynamic_cast or any kind of run time type checking since the program has got static knowledge of types: look at the function derived2() in the example I showed: it statically returns a boost::shared_ptr. Don't know how shared_ptr support is implemented, guess it's not trivial... However managed to get around the problem with a simple hack: prior to pass a shared_ptr to Python for the first time, I just pass it to Python casted to its most-derived class. On Sun, Mar 21, 2010 at 10:28 PM, Nat Goodspeed wrote: > peoro wrote: > >> Ok, it does work as expected if class Base has got at least one virtual >> member: >> >> ...What if I cannot add a virtual function to the class Base? > > If your C++ base class has no virtual methods, even pure C++ can't > dynamic_cast<> it. > > Put differently -- you've been asking Python to determine the runtime type > of a class for which C++ maintains no runtime type. It's the presence of at > least one virtual method that forces C++ to start tracking the runtime type > of a class hierarchy. > _______________________________________________ > Cplusplus-sig mailing list > Cplusplus-sig at python.org > http://mail.python.org/mailman/listinfo/cplusplus-sig > From troy at resophonic.com Mon Mar 22 00:21:36 2010 From: troy at resophonic.com (troy d. straszheim) Date: Sun, 21 Mar 2010 19:21:36 -0400 Subject: [C++-sig] Boost.Python and PEP 384 In-Reply-To: References: Message-ID: <4BA6AA00.1080007@resophonic.com> Skip Montanaro wrote: > Do Boost.Python-generated extension modules conform to PEP 384's > constraints for ABI compatibility? > Thanks for pointing that out. Without looking too closely, I doubt that boost.python conforms. I'd give it a try, but it looks like I need to wait for python 3.2, then turn on Py_LIMITED_API when compiling. (Do I have that right?) -t From swarfrat at gmail.com Mon Mar 22 00:55:16 2010 From: swarfrat at gmail.com (Nathan Stewart) Date: Sun, 21 Mar 2010 19:55:16 -0400 Subject: [C++-sig] Current Docs for wrapping idexable containers Message-ID: <9857ba051003211655i674bd120p4639f3b7fc6715e8@mail.gmail.com> I'm sorting through the umpteen generations of documentation and mailing lists preserved forever on internet and trying to determine how to be wrap this third party pseudo-vector class. (OMG folks like to write their own types for everything) The OMG sequence does provide operator[], and I need to track allocated storage space and be able to throw on out of bounds indices. I'm sure what I'm trying to do is really basic, but my attempts to wrap operator[] are failing and I think it's likely to using the wrong set of docs. (For instance has relocated since the docs I was following were written.) What should I be looking at? -------------- next part -------------- An HTML attachment was scrubbed... URL: From nat at lindenlab.com Mon Mar 22 02:20:52 2010 From: nat at lindenlab.com (Nat Goodspeed) Date: Sun, 21 Mar 2010 21:20:52 -0400 Subject: [C++-sig] [Py++] boost::shared_ptr casting In-Reply-To: <1c7ed23c1003211551o691a8e97o3e0532aeac225586@mail.gmail.com> References: <1c7ed23c1003201331o1d00fccr5d7e4a71478eaaf2@mail.gmail.com> <1269119202.2301.3.camel@bishop> <1c7ed23c1003201907v44fccad9gc23c02eb36c631f@mail.gmail.com> <7465b6171003202211p2595918ai3be07419c65c3b96@mail.gmail.com> <1c7ed23c1003210712t9b5b520w7440bc20386ff24a@mail.gmail.com> <4BA68F65.5030305@lindenlab.com> <1c7ed23c1003211551o691a8e97o3e0532aeac225586@mail.gmail.com> Message-ID: <4BA6C5F4.5000508@lindenlab.com> peoro wrote: > There should be no need of dynamic_cast or any kind of run time type > checking since the program has got static knowledge of types: The C++ program may have that knowledge. All I'm saying is that your original issue concerned Python determining the runtime type (leaf class) of each object. > managed to get around the problem with a simple > hack: prior to pass a shared_ptr to Python for the first time, I just > pass it to Python casted to its most-derived class. I'm glad you've got a solution that works for you. From hitesh.dhiman.1988 at gmail.com Mon Mar 22 02:44:06 2010 From: hitesh.dhiman.1988 at gmail.com (hitesh dhiman) Date: Mon, 22 Mar 2010 09:44:06 +0800 Subject: [C++-sig] vc++ assertion error upon runtime In-Reply-To: <1268981439.4936.1.camel@bishop> References: <1268981439.4936.1.camel@bishop> Message-ID: Hi Jim, Well, the code's rather official, so i won't be able to give the exact details, but here's the code simplified: CFunctionRequest( pData, (DWORD*)&ucmmReq.len) where pData is BYTE pData[512]; and typedef struct { int len; char* data; } Data; with Data ucmmReq The definition for the CFunctionRequest is CFunctionRequest(BYTE* pRequest, DWORD* pLength) This is where the problem occurs. Above this, it works fine. Do let me know if some more info is needed. Thanks. On Fri, Mar 19, 2010 at 2:50 PM, Jim Bosch wrote: > On Fri, 2010-03-19 at 14:45 +0800, hitesh dhiman wrote: > > Hi all, > > I'm trying to gain access to functions that use pointers as > > arguments. I have written the wrapper file that converts the arguments > > into pointers. The compilation works successfully, but when i try to > > run the code from python, it gives an assertion error: > > Debug Assertion Failed! > > Expression: Vector subscript out of range > > > > > > Surprisingly, this error only occurs when a particular function is > > called, Until that point, the code works perfectly. > > > > > > Could someone guide me what to do?? > > You'll need to provide some more information. Could you post a > simplified version of your code that demonstrates the problem? > > Jim > > > > > _______________________________________________ > Cplusplus-sig mailing list > Cplusplus-sig at python.org > http://mail.python.org/mailman/listinfo/cplusplus-sig > -- Regards, Hitesh Dhiman Electrical Engineering National University of Singapore -------------- next part -------------- An HTML attachment was scrubbed... URL: From talljimbo at gmail.com Mon Mar 22 03:44:10 2010 From: talljimbo at gmail.com (Jim Bosch) Date: Sun, 21 Mar 2010 19:44:10 -0700 Subject: [C++-sig] vc++ assertion error upon runtime In-Reply-To: References: <1268981439.4936.1.camel@bishop> Message-ID: <1269225851.11769.14.camel@bishop> On Fri, 2010-03-19 at 14:45 +0800, hitesh dhiman wrote: > > Hi all, > > I'm trying to gain access to functions that use pointers as > > arguments. I have written the wrapper file that converts the > arguments > > into pointers. The compilation works successfully, but when > i try to > > run the code from python, it gives an assertion error: > > Debug Assertion Failed! > > Expression: Vector subscript out of range > On Mon, 2010-03-22 at 09:44 +0800, hitesh dhiman wrote: > Hi Jim, > Well, the code's rather official, so i won't be able to give the exact > details, but here's the code simplified: > > > CFunctionRequest( pData, (DWORD*)&ucmmReq.len) > where pData is BYTE pData[512]; > and > typedef struct > { > int len; > char* data; > } Data; > with Data ucmmReq > > > The definition for the CFunctionRequest is CFunctionRequest(BYTE* > pRequest, DWORD* pLength) > This is where the problem occurs. Above this, it works fine. > Do let me know if some more info is needed. > Thanks. > Do you think this "debug assertion" is happening in Boost.Python code somewhere? I assume it's somewhere in the code you are wrapping. I also can't help but notice that your C functions seem to take arrays, not pointers to scalar values, and that leaves me rather confused as to what type of Python object you could be taking as input and converting into an array. Jim From hitesh.dhiman.1988 at gmail.com Mon Mar 22 09:56:29 2010 From: hitesh.dhiman.1988 at gmail.com (hitesh dhiman) Date: Mon, 22 Mar 2010 16:56:29 +0800 Subject: [C++-sig] vc++ assertion error upon runtime In-Reply-To: <1269225851.11769.14.camel@bishop> References: <1268981439.4936.1.camel@bishop> <1269225851.11769.14.camel@bishop> Message-ID: Hey Jim I found out where the problem was. This function is actually reading out null values, hence the error. There was a problem in the execution of the code before it. I was able to solve it by commenting out this part and print out the values step by step. One of the dll's being used was not registered, and so CoCreateInstance was giving out a -ve value on loading the dll, and this function was accessing vectors that were not initialized by the previous function. Thanks for the help! On Mon, Mar 22, 2010 at 10:44 AM, Jim Bosch wrote: > On Fri, 2010-03-19 at 14:45 +0800, hitesh dhiman wrote: > > > Hi all, > > > I'm trying to gain access to functions that use pointers as > > > arguments. I have written the wrapper file that converts the > > arguments > > > into pointers. The compilation works successfully, but when > > i try to > > > run the code from python, it gives an assertion error: > > > Debug Assertion Failed! > > > Expression: Vector subscript out of range > > > On Mon, 2010-03-22 at 09:44 +0800, hitesh dhiman wrote: > > Hi Jim, > > Well, the code's rather official, so i won't be able to give the exact > > details, but here's the code simplified: > > > > > > CFunctionRequest( pData, (DWORD*)&ucmmReq.len) > > where pData is BYTE pData[512]; > > and > > typedef struct > > { > > int len; > > char* data; > > } Data; > > with Data ucmmReq > > > > > > The definition for the CFunctionRequest is CFunctionRequest(BYTE* > > pRequest, DWORD* pLength) > > This is where the problem occurs. Above this, it works fine. > > Do let me know if some more info is needed. > > Thanks. > > > > Do you think this "debug assertion" is happening in Boost.Python code > somewhere? I assume it's somewhere in the code you are wrapping. > > I also can't help but notice that your C functions seem to take arrays, > not pointers to scalar values, and that leaves me rather confused as to > what type of Python object you could be taking as input and converting > into an array. > > Jim > > > > > _______________________________________________ > Cplusplus-sig mailing list > Cplusplus-sig at python.org > http://mail.python.org/mailman/listinfo/cplusplus-sig > -- Regards, Hitesh Dhiman Electrical Engineering National University of Singapore -------------- next part -------------- An HTML attachment was scrubbed... URL: From cmbruns at stanford.edu Thu Mar 25 19:34:14 2010 From: cmbruns at stanford.edu (Christopher Bruns) Date: Thu, 25 Mar 2010 11:34:14 -0700 Subject: [C++-sig] [Py++] Registration order corner case Message-ID: Py++ has produced for me over 97,000 lines of beautiful boost.python wrapping code on my project, using less than 2500 lines of python. But I am still experiencing some minor troubles that prevent me from completing my project. Suppose I wish to wrap the following: //###### foo.h ########### struct Foo1 { struct Foo2; }; struct Foo3 : public Foo1 {}; struct Foo1::Foo2 : public Foo3 {}; then, pyplusplus generates code like this: //###### foo_module.cpp ####### #include "boost/python.hpp" #include "foo.h" namespace bp = boost::python; BOOST_PYTHON_MODULE(_foo){ bp::class_< Foo3, bp::bases< Foo1 > >( "Foo3" ); { //::Foo1 typedef bp::class_< Foo1 > Foo1_exposer_t; Foo1_exposer_t Foo1_exposer = Foo1_exposer_t( "Foo1" ); bp::scope Foo1_scope( Foo1_exposer ); bp::class_< Foo1::Foo2, bp::bases< Foo3 > >( "Foo2" ); } } When I try to use this module, "from _foo import *", I get a RuntimeError: "RuntimeError: extension class wrapper for base class struct Foo1 has not been created yet" If I then move the registration of "Foo3" to below the Foo1 block in the py++ generated code, I get a new RunTimeError: BOOST_PYTHON_MODULE(_foo){ { //::Foo1 typedef bp::class_< Foo1 > Foo1_exposer_t; Foo1_exposer_t Foo1_exposer = Foo1_exposer_t( "Foo1" ); bp::scope Foo1_scope( Foo1_exposer ); bp::class_< Foo1::Foo2, bp::bases< Foo3 > >( "Foo2" ); } bp::class_< Foo3, bp::bases< Foo1 > >( "Foo3" ); } "RuntimeError: extension class wrapper for base class struct Foo3 has not been created yet The only way to avoid the registration order problem is to register these classes to boost.python in exactly the order Foo1, Foo3, Foo2 (just like the definitions in C++). #include "boost/python.hpp" #include "foo.h" namespace bp = boost::python; BOOST_PYTHON_MODULE(_foo){ typedef bp::class_< Foo1 > Foo1_exposer_t; Foo1_exposer_t Foo1_exposer = Foo1_exposer_t( "Foo1" ); bp::class_< Foo3, bp::bases< Foo1 > >( "Foo3" ); bp::scope Foo1_scope( Foo1_exposer ); bp::class_< Foo1::Foo2, bp::bases< Foo3 > >( "Foo2" ); } Is there a way to coax pyplusplus to produce this registration order? From roman.yakovenko at gmail.com Thu Mar 25 20:09:12 2010 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Thu, 25 Mar 2010 21:09:12 +0200 Subject: [C++-sig] [Py++] Registration order corner case In-Reply-To: References: Message-ID: <7465b6171003251209v20410155vb4a5cd8ff006d11@mail.gmail.com> On Thu, Mar 25, 2010 at 8:34 PM, Christopher Bruns wrote: > Py++ has produced for me over 97,000 lines of beautiful boost.python > wrapping code on my project, using less than 2500 lines of python. :-)))). I would say this is pretty good ratio > But I am still experiencing some minor troubles that prevent me from > completing my project. > > Suppose I wish to wrap the following: > > //###### foo.h ########### > struct Foo1 { struct Foo2; }; > struct Foo3 : public Foo1 {}; > struct Foo1::Foo2 : public Foo3 {}; > ... I am pretty sure Py++ doesn't export such hierarchies right. The class sorting algorithm is a simple DFS, which doesn't take into account such use case - "derived from the inner class" > The only way to avoid the registration order problem is to register > these classes to boost.python in exactly the order Foo1, Foo3, Foo2 > (just like the definitions in C++). > > #include "boost/python.hpp" > #include "foo.h" > namespace bp = boost::python; > BOOST_PYTHON_MODULE(_foo){ > ? ?typedef bp::class_< Foo1 > Foo1_exposer_t; > ? ?Foo1_exposer_t Foo1_exposer = Foo1_exposer_t( "Foo1" ); > > ? ?bp::class_< Foo3, bp::bases< Foo1 > >( "Foo3" ); > > ? ?bp::scope Foo1_scope( Foo1_exposer ); > ? ?bp::class_< Foo1::Foo2, bp::bases< Foo3 > >( "Foo2" ); > } > > Is there a way to coax pyplusplus to produce this registration order? Yes. if : I suggest you to take a look on "pyplusplus/creators_factory/sort_algorithms.py" file. It contains class_organizer_t class, which is responsible for defining the order of the classes for exporting. As I already said, it implements a simple DFS that doesn't take many details into account. It could be nice to get this algorithm right in your use case too. The class tester is located under pyplusplus_dev/unittests/algorithms_tester.py - class class_organizer_tester_t. else: #If you don't have time: pyplusplus/creators_factory/sort_algorithms.py contains sort_classes function, which is a convenience wrapper around class_organizer_t class. You can replace this function with your own one: pypp_sort_classes = pyplusplus/creators_factory/sort_algorithms.sort_classes def my_sort_classes( classes, include_vars=False ) sorted = pypp_sort_classes( classes, include_vars ) < put class X before class Y > return sorted pyplusplus/creators_factory/sort_algorithms.sort_classes = my_sort_classes If you have even less time, you always can modified file by hands, create the patch and apply it every time after code generation process. HTH -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From cmbruns at stanford.edu Thu Mar 25 21:23:34 2010 From: cmbruns at stanford.edu (Christopher Bruns) Date: Thu, 25 Mar 2010 13:23:34 -0700 Subject: [C++-sig] [Py++] Registration order corner case In-Reply-To: <7465b6171003251209v20410155vb4a5cd8ff006d11@mail.gmail.com> References: <7465b6171003251209v20410155vb4a5cd8ff006d11@mail.gmail.com> Message-ID: Thanks Roman for your swift and thoughtful advice. Your feedback on this list is one of many admirable features of Py++. I believe that the issue here goes a bit deeper than the classes' sort order (see below) On Thu, Mar 25, 2010 at 12:09 PM, Roman Yakovenko wrote: > On Thu, Mar 25, 2010 at 8:34 PM, Christopher Bruns wrote: >> ... >> //###### foo.h ########### >> struct Foo1 { struct Foo2; }; >> struct Foo3 : public Foo1 {}; >> struct Foo1::Foo2 : public Foo3 {}; >> ... > > I am pretty sure Py++ doesn't export such hierarchies right. The class > sorting algorithm is a simple DFS, which doesn't take into account > such use case - "derived from the inner class" > >> The only way to avoid the registration order problem is to register >> these classes to boost.python in exactly the order Foo1, Foo3, Foo2 >> (just like the definitions in C++). >> >> #include "boost/python.hpp" >> #include "foo.h" >> namespace bp = boost::python; >> BOOST_PYTHON_MODULE(_foo){ >> ? ?typedef bp::class_< Foo1 > Foo1_exposer_t; >> ? ?Foo1_exposer_t Foo1_exposer = Foo1_exposer_t( "Foo1" ); >> >> ? ?bp::class_< Foo3, bp::bases< Foo1 > >( "Foo3" ); >> >> ? ?bp::scope Foo1_scope( Foo1_exposer ); >> ? ?bp::class_< Foo1::Foo2, bp::bases< Foo3 > >( "Foo2" ); >> } >> >> Is there a way to coax pyplusplus to produce this registration order? > > Yes. > ... > pyplusplus/creators_factory/sort_algorithms.py contains sort_classes > function, which is a convenience wrapper around class_organizer_t > class. You can replace this function with your own one: > > pypp_sort_classes = pyplusplus/creators_factory/sort_algorithms.sort_classes > > def my_sort_classes( classes, include_vars=False ) > ? ?sorted = pypp_sort_classes( classes, include_vars ) > ? ?< put class X before class Y > > ? ?return sorted > > pyplusplus/creators_factory/sort_algorithms.sort_classes = my_sort_classes I hacked in a sort order that hard-codes the correct order of these three classes (Foo1, Foo3, Foo2), and yet pyplusplus generates this: ######################### BOOST_PYTHON_MODULE(_foo){ { //::Foo1 typedef bp::class_< Foo1 > Foo1_exposer_t; Foo1_exposer_t Foo1_exposer = Foo1_exposer_t( "Foo1" ); bp::scope Foo1_scope( Foo1_exposer ); bp::class_< Foo1::Foo2, bp::bases< Foo3 > >( "Foo2" ); } bp::class_< Foo3, bp::bases< Foo1 > >( "Foo3" ); } ######################### "RuntimeError: extension class wrapper for base class struct Foo3 has not been created yet" It seems that because Foo2 is an inner class of Foo1, it is always registered in the same block as Foo1. There is no way for Foo3 to get registered in between. Perhaps py++ does not yet have a way to separate the declaration of an outer class from the declaration of its inner classes. Further, because I prefer to use the one-file-per class wrapping feature of py++, there would need to be a separate file for Foo2, which is ordinarily declared in the file Foo1.pypp.cpp, for this case to work in "split_module" mode. Regards, Christopher From swarfrat at gmail.com Thu Mar 25 21:33:52 2010 From: swarfrat at gmail.com (Nathan Stewart) Date: Thu, 25 Mar 2010 16:33:52 -0400 Subject: [C++-sig] examples for add_override_precall_code? Message-ID: <9857ba051003251333h64071d5br29688f6cfb7ac1d0@mail.gmail.com> I have pyplusplus churning out code, now I'm trying to get it to resemble what I need. I need to use add_override_precall_code, to add some thread locking to my overrides, but I can't seem to figure out how to use it from the docs. Also, I have a set of overloaded virtual functions, and previously I've had a wrapper class where the python exports rename the overloads, like so: class Connection { virtual void Callback(const Type_A&); virtual void Callback(const Type_B&); } the wrapper looked like: ConnectionWrap : Connection, wrapper { void Callback(const Type_A& arg) { ScopedGILLock lock(m_state); // the reason I'm trying to figure out add_override_porecall_code if (override o = this->get_override("Callback_Type_A")) { o(arg); } } }; I'm getting the rest of the override as above, but setting use_overload_macro doesn't rename the overloads as I need. Any clues (since pointers are references are both 'overloaded' in this context') -------------- next part -------------- An HTML attachment was scrubbed... URL: From roman.yakovenko at gmail.com Thu Mar 25 22:20:18 2010 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Thu, 25 Mar 2010 23:20:18 +0200 Subject: [C++-sig] [Py++] Registration order corner case In-Reply-To: References: <7465b6171003251209v20410155vb4a5cd8ff006d11@mail.gmail.com> Message-ID: <7465b6171003251420l7d9ed289v2f8119fb4ba8c979@mail.gmail.com> On Thu, Mar 25, 2010 at 10:23 PM, Christopher Bruns wrote: > Thanks Roman for your swift and thoughtful advice. ?Your feedback on > this list is one of many admirable features of Py++. Thank you! > I believe that the issue here goes a bit deeper than the classes' sort > order (see below) You are right. > It seems that because Foo2 is an inner class of Foo1, it is always > registered in the same block as Foo1. ?There is no way for Foo3 to get > registered in between. ?Perhaps py++ does not yet have a way to > separate the declaration of an outer class from the declaration of its > inner classes. You are right once again. When I developed the package I thought about inner classes as some helper classes( small and "final" ). > Further, because I prefer to use the one-file-per > class wrapping feature of py++, there would need to be a separate file > for Foo2, which is ordinarily declared in the file Foo1.pypp.cpp, for > this case to work in ?"split_module" mode. Is this an option to "drop" base classes: mb.class_( 'Foo1' ).bases[0].access_type = declarations.ACCESS_TYPES.PRIVATE mb.class_( 'Foo3' ).bases[0].access_type = declarations.ACCESS_TYPES.PRIVATE This will work, but I can't enumerate the things that will not be exported ( bad memory :-) ). If not, then there is one more option, but you definitely not going to like it - to manipulate code creators tree. It works: http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1832&view=rev The following code: struct foo1_t{ struct foo2_t; }; struct foo3_t : public foo1_t{}; struct foo1_t::foo2_t : public foo3_t{}; was exposed using code_creators tree manipulation: mb.build_code_creator( self.EXTENSION_NAME ) foo3 = mb.code_creator.body.creators[0] del mb.code_creator.body.creators[0] mb.code_creator.body.creators[0].adopt_creator( foo3, 0) and the generated code is: BOOST_PYTHON_MODULE(inner_base_class){ { //::foo1_t typedef bp::class_< foo1_t > foo1_t_exposer_t; foo1_t_exposer_t foo1_t_exposer = foo1_t_exposer_t( "foo1_t", "documentation" ); bp::scope foo1_t_scope( foo1_t_exposer ); bp::class_< foo3_t, bp::bases< foo1_t > >( "foo3_t", "documentation" ); bp::class_< foo1_t::foo2_t, bp::bases< foo3_t > >( "foo2_t", "documentation" ); } } There is another problem with that code: class foo3_t is exposed under class foo1_t. You can fix this using a simple Python code: foo3_t = .foo1_t.foo3_t The only other solution is "patching" the generated code. HTH -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From roman.yakovenko at gmail.com Thu Mar 25 22:34:54 2010 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Thu, 25 Mar 2010 23:34:54 +0200 Subject: [C++-sig] examples for add_override_precall_code? In-Reply-To: <9857ba051003251333h64071d5br29688f6cfb7ac1d0@mail.gmail.com> References: <9857ba051003251333h64071d5br29688f6cfb7ac1d0@mail.gmail.com> Message-ID: <7465b6171003251434m7a315d79xa4235634ae7cc886@mail.gmail.com> On Thu, Mar 25, 2010 at 10:33 PM, Nathan Stewart wrote: > I have pyplusplus churning out code, now I'm trying to get it to resemble > what I need. I need to use add_override_precall_code, to add some thread > locking to my overrides, but I can't seem to figure out how to use it from > the docs. Can you ask more concrete question? Basically "add_override_precall_code" method has single argument - the code you want to add before calling "override" function. > Also, I have a set of overloaded virtual functions, and previously > I've had a wrapper class where the python exports rename the overloads, like > so: > > class Connection > { > ??? virtual void Callback(const Type_A&); > ??? virtual void Callback(const Type_B&); > } > > the wrapper looked like: > > ConnectionWrap : Connection, wrapper > { > ??? void Callback(const Type_A& arg) > ??? { > ??????? ScopedGILLock lock(m_state); // the reason I'm trying to figure out > add_override_porecall_code > ??????? if (override o = this->get_override("Callback_Type_A")) > ??????? { o(arg);? } > ??? } > }; > > > I'm getting the rest of the override as above, but setting > use_overload_macro doesn't rename the overloads as I need. Any clues (since > pointers are references are both 'overloaded' in this context') use_overload_macro generates code that uses "BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS" macro ( see Boost.Python reference for explanation ). I guess what you want to use/change is the function alias: mb = module_builder_t ( .... ) connection = mb.class_( 'Connection' ) for callback in connection.mem_funs( 'Callback' ): callback.alias = < create new alias name based in argument types and original function name> HTH -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From cmbruns at stanford.edu Thu Mar 25 22:48:44 2010 From: cmbruns at stanford.edu (Christopher Bruns) Date: Thu, 25 Mar 2010 14:48:44 -0700 Subject: [C++-sig] [Py++] Registration order corner case In-Reply-To: <7465b6171003251420l7d9ed289v2f8119fb4ba8c979@mail.gmail.com> References: <7465b6171003251209v20410155vb4a5cd8ff006d11@mail.gmail.com> <7465b6171003251420l7d9ed289v2f8119fb4ba8c979@mail.gmail.com> Message-ID: On Thu, Mar 25, 2010 at 2:20 PM, Roman Yakovenko wrote: >... > Is this an option to "drop" base classes: >... > If not, then there is one more option, but you definitely not going to > like it - to manipulate code creators tree. >... Thanks for the in depth explanation. I am glad to learn that there is a way. But not an easy way. I now realize that it is not so hard for me to change this one part of the API I am wrapping. So I am taking the easiest way out by changing the API to avoid inner classes derived from non-inner classes. By the time I figured out what the problem was, I was nearly ready to make this bug report, so that's what I did. Thanks again for all of your help. It is truly helpful. Christopher From macieksitarz at wp.pl Sat Mar 27 18:18:38 2010 From: macieksitarz at wp.pl (Maciej Sitarz) Date: Sun, 28 Mar 2010 02:18:38 +0900 Subject: [C++-sig] Problems with boost tuples to python conversion Message-ID: <4BAE3DEE.6050109@wp.pl> Hi, I tried to expose objects of class: typedef boost::tuple RegisterResult; to python. I used automatic conversion (http://www.language-binding.net/pyplusplus/troubleshooting_guide/automatic_conversion/automatic_conversion.html) but as usual I hit a wall and got unsolvable error. INFO gccxml cmd: /usr/bin/gccxml -I"." -I"/home/macieks/error_examples/boost_tuples_to_python" -I"/usr/include" -I"/usr/include/python2.4" -I"/home/macieks/boost/boost_1_42_0" "test.h" -fxml="/tmp/tmp9Kp4rg.xml" Traceback (most recent call last): File "generate.py", line 14, in ? indexing_suite_version=2 File "usr/lib/python2.4/site-packages/pyplusplus/module_builder/boost_python_builder.py", line 95, in __init__ File "usr/lib/python2.4/site-packages/pyplusplus/module_builder/boost_python_builder.py", line 138, in __parse_declarations File "usr/lib/python2.4/site-packages/pygccxml/parser/project_reader.py", line 217, in read_files File "usr/lib/python2.4/site-packages/pygccxml/parser/project_reader.py", line 242, in __parse_file_by_file File "usr/lib/python2.4/site-packages/pygccxml/parser/source_reader.py", line 206, in read_file File "usr/lib/python2.4/site-packages/pygccxml/parser/source_reader.py", line 231, in read_gccxml_file pygccxml.parser.source_reader.gccxml_runtime_error_t: Error occured while running GCC-XML: /home/macieks/boost/boost_1_42_0/boost/mpl/bool_fwd.hpp:21: sorry, unimplemented: call_expr cannot be mangled due to a defect in the C++ ABI I tried to use tuples.hpp from pyogre (it has some few lines added), but the problem is the same. I attached simple example files to this mail. Best regards -- Maciek Sitarz -------------- next part -------------- A non-text attachment was scrubbed... Name: generate.py Type: text/x-python Size: 654 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: test.h Type: text/x-chdr Size: 640 bytes Desc: not available URL: From roman.yakovenko at gmail.com Sat Mar 27 19:12:45 2010 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Sat, 27 Mar 2010 21:12:45 +0300 Subject: [C++-sig] Problems with boost tuples to python conversion In-Reply-To: <4BAE3DEE.6050109@wp.pl> References: <4BAE3DEE.6050109@wp.pl> Message-ID: <7465b6171003271112l31492066sacd0d570f79be575@mail.gmail.com> On Sat, Mar 27, 2010 at 8:18 PM, Maciej Sitarz wrote: > Hi, > I tried to expose objects of class: > typedef boost::tuple RegisterResult; > to python. > > I used automatic conversion > (http://www.language-binding.net/pyplusplus/troubleshooting_guide/automatic_conversion/automatic_conversion.html) > but as usual I hit a wall and got unsolvable error. > > INFO gccxml cmd: /usr/bin/gccxml ?-I"." > -I"/home/macieks/error_examples/boost_tuples_to_python" -I"/usr/include" > -I"/usr/include/python2.4" -I"/home/macieks/boost/boost_1_42_0" "test.h" > -fxml="/tmp/tmp9Kp4rg.xml" > Traceback (most recent call last): > ?File "generate.py", line 14, in ? > ? ?indexing_suite_version=2 > ?File > "usr/lib/python2.4/site-packages/pyplusplus/module_builder/boost_python_builder.py", > line 95, in __init__ > ?File > "usr/lib/python2.4/site-packages/pyplusplus/module_builder/boost_python_builder.py", > line 138, in __parse_declarations > ?File "usr/lib/python2.4/site-packages/pygccxml/parser/project_reader.py", > line 217, in read_files > ?File "usr/lib/python2.4/site-packages/pygccxml/parser/project_reader.py", > line 242, in __parse_file_by_file > ?File "usr/lib/python2.4/site-packages/pygccxml/parser/source_reader.py", > line 206, in read_file > ?File "usr/lib/python2.4/site-packages/pygccxml/parser/source_reader.py", > line 231, in read_gccxml_file > pygccxml.parser.source_reader.gccxml_runtime_error_t: Error occured while > running GCC-XML: /home/macieks/boost/boost_1_42_0/boost/mpl/bool_fwd.hpp:21: > sorry, unimplemented: call_expr cannot be mangled due to a defect in the C++ > ABI > Unfortunately, GCCXML is not able to compile many of the Boost libraries. You will have to change your code. Sorry, but I don't have better solution for you. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From macieksitarz at wp.pl Sun Mar 28 03:53:58 2010 From: macieksitarz at wp.pl (Maciej Sitarz) Date: Sun, 28 Mar 2010 10:53:58 +0900 Subject: [C++-sig] Problems with boost tuples to python conversion In-Reply-To: <7465b6171003271112l31492066sacd0d570f79be575@mail.gmail.com> References: <4BAE3DEE.6050109@wp.pl> <7465b6171003271112l31492066sacd0d570f79be575@mail.gmail.com> Message-ID: <4BAEB6B6.2000409@wp.pl> On 28.03.2010 03:12, Roman Yakovenko wrote: > > Unfortunately, GCCXML is not able to compile many of the Boost > libraries. You will have to change your code. > > Sorry, but I don't have better solution for you. So that would be a big problem, because that's a C++ API for a library which isn't developed by me. Maybe you know how the pyogre developers handled this situation? The tuple.hpp is from theirs repo, but I didn't manage to investigate how did they do it. Thanks -- Maciek Sitarz From roman.yakovenko at gmail.com Sun Mar 28 11:53:57 2010 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Sun, 28 Mar 2010 12:53:57 +0300 Subject: [C++-sig] Problems with boost tuples to python conversion In-Reply-To: <4BAEB6B6.2000409@wp.pl> References: <4BAE3DEE.6050109@wp.pl> <7465b6171003271112l31492066sacd0d570f79be575@mail.gmail.com> <4BAEB6B6.2000409@wp.pl> Message-ID: <7465b6171003280253x1321259fv43c5bcc049b564df@mail.gmail.com> On Sun, Mar 28, 2010 at 4:53 AM, Maciej Sitarz > So that would be a big problem, because that's a C++ API for a library which > isn't developed by me. > Maybe you know how the pyogre developers handled this situation? The > tuple.hpp is from theirs repo, but I didn't manage to investigate how did > they do it. I sent the question to PyOgre main developer. When the answer will be available, I will publish it here. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From swarfrat at gmail.com Mon Mar 29 03:08:30 2010 From: swarfrat at gmail.com (Nathan Stewart) Date: Sun, 28 Mar 2010 21:08:30 -0400 Subject: [C++-sig] custom r-value converters Message-ID: <9857ba051003281808k1d4bc3b0x4d4006c04af34d05@mail.gmail.com> I have to interface with a custom string class. In my handwritten code, I had the example from http://www.boost.org/doc/libs/1_42_0/libs/python/doc/v2/faq.html#custom_stringworking. I'm working with an custom string class. Actually they have a String_mgr class which derives from a String_val, and exposes the string as a property called 'val'. And py++ wraps the String_mgr as an opaque structure with a working 'val' property. But the String_mgr class in c++ supports assignment and casting, and that part doesn't work even though I have done an mb.class_('String_mgr').add_properties(exclude_accessors=False). In my application code I have numerous instances of this String_mgr. I'd like to be able to contain my interactions with the particulars of String_mgr to the one definition and not have to do an .add_property('foo', getter, setter) for each and every occurence of their String_mgr class (which are quite numerous). Can I make assignment and casting work in this way, or must I modify each and every String_mgr occurence as a property? Just in case it's not clear, I have struct ClassOne { String_mgr name; } struct ClassTwo { String_mgr description; } and I want to confine all my handling specific to the String_mgr class to one location and let the wrapping of String_mgr handle the property get/set (ClassOne, etc... are IDL generated and numerous.) I can't seem to both wrap the String_mgr class and have custom converters - I'm told I have a duplicate registration. Can I get both automatic conversion and the ability to treat this wrapped class as a property of other classes? It seems to trigger on the assignment & casting but I'm just not getting it right now. -------------- next part -------------- An HTML attachment was scrubbed... URL: From swarfrat at gmail.com Mon Mar 29 09:08:50 2010 From: swarfrat at gmail.com (Nathan Stewart) Date: Mon, 29 Mar 2010 03:08:50 -0400 Subject: [C++-sig] custom r-value converters In-Reply-To: <9857ba051003281808k1d4bc3b0x4d4006c04af34d05@mail.gmail.com> References: <9857ba051003281808k1d4bc3b0x4d4006c04af34d05@mail.gmail.com> Message-ID: <9857ba051003290008i75706ffdjf712cab02b011d8d@mail.gmail.com> Ok some follow up - I now rip through my exposed classes looking for String_mgr typed properties to create custom get/setters for.Then, I set the following for that property: for c in classes: for property in c.public_members: if 'CustomString' in property.decl_string: property.set_use_make_functions( True ) property.set_getter_call_policies( property.return_by_value ) property.set_setter_call_policies( property.return_by_value ) What is generated instead looks like this .add_property( "name" , bp::make_getter( &Update::name, bp::return_internal_reference< >() ) , bp::make_setter( &Update::name ) ) when I expected it to look like: .add_property( "name" , bp::make_getter( &Update::name, bp::return_by_value() ) , bp::make_setter( &Update::namem bp::return_by_value() ) ) It's a property, and it occurs to me that it might not be a callable object. But I don't have one at this point - make_getter/setter is creating it. What am I doing wrong here? -------------- next part -------------- An HTML attachment was scrubbed... URL: From cmbruns at stanford.edu Mon Mar 29 22:28:13 2010 From: cmbruns at stanford.edu (Christopher Bruns) Date: Mon, 29 Mar 2010 13:28:13 -0700 Subject: [C++-sig] Conversion of python files to C++ ostreams Message-ID: I am trying to coax boost.python to automatically convert python files to C++ std::ostreams, for methods that take arguments of type "std::ostream&". I have made some progress, and I could use some advice on how to go further. I created a derived class of std::ostream, called FilestarOstream, which takes a std::FILE* as it constructor argument. Then I created a conversion from "python file" to the FilestarOstream class. Now my python module can automatically convert a python file to a FilestarOstream for any method that takes a "const FilestarOstream&" as an argument. Ideally I would prefer to automatically convert a python file for any method that takes a (non-const) "std::ostream&" as an argument. I have included my simplified source code below My questions: 1 - Is there an easier way to do this? Does boost.python have a built in incantation for wrapping methods that take a std::ostream reference, to take python files? 2 - Is there a way to make the type conversion work for non-const reference arguments? (see print_hello_wrapper2() below) 3 - Why does my print_hello_wrapper3() not work? It takes a const std::ostream reference argument. I can pass it a FileStarOstream, so python knows how to convert a FileStarOstream to a std::ostream. Plus python knows how to convert a python file to a const FileStarOstream reference. So why can't it convert a python file to a const ostream reference? 4 - In my FilestarOstream_from_pyfile::convertible method, is there a way to check that the object is not only a file, but that it is also writable? 5 - The PyFile_AsFile docs say "If the caller will ever use the returned FILE* object while the GIL is released it must also call the PyFile_IncUseCount() and PyFile_DecUseCount() functions described below as appropriate." What is "the GIL". If I call PyFile_IncUseCount() when I construct the FileStarOstream, when would I call the corresponding PyFile_DecUseCount()? Thanks in advance for any helpful tips. ################## //// begin test.hpp //////// #ifndef TEST_API_PYFILE_OSTREAM_H_ #define TEST_API_PYFILE_OSTREAM_H_ #include // This is the sort of method I wish to wrap std::ostream& print_hello(std::ostream& os, int foo); // FilestarOstream is intended to aid python wrapping of methods that // take ostream& args by converting an opaque C++ FILE* to a C++ ostream. // This is just one part of the (yet unproven) task of automatically // wrapping methods that take an ostream& as an argument. class FilestarOstream : public std::ostream { public: // std::ostreams can be constructed using an std::streambuf // so the first step is to construct a specialized std::streambuf // based on a FILE* // Adapted from // http://mail.python.org/pipermail/cplusplus-sig/2002-June/000896.html class std_obuf: public std::streambuf { public: std_obuf(std::FILE* file): m_file(file) {} std::FILE* updFilestar() {return m_file;} protected: std::streambuf::int_type overflow(std::streambuf::int_type c) { return std::fputc(c, m_file) == EOF ? std::streambuf::traits_type::eof() : c; } std::FILE* m_file; }; FilestarOstream(std::FILE* fp) : buf(fp), std::ostream(&buf) {} // Default constructor uses stdout FilestarOstream() : buf(stdout), std::ostream(&buf) {} std::FILE* updFilestar() {return buf.updFilestar();} protected: std_obuf buf; }; #endif // TEST_API_PYFILE_OSTREAM_H_ //////////// end test.hpp ////////// ################### //// test.cpp /// #include "test.hpp" std::ostream& print_hello(std::ostream& os, int foo) { os << "Hello, foo = " << foo << std::endl; return os; } /// end test.cpp /// ###################### // boost.python wrapping code #include "boost/python.hpp" #include "test.hpp" namespace bp = boost::python; // Three ways of wrapping print_hello() to take a python file argument, // only one of which works: // print_hello_wrapper1() works, but I wish I did not need a wrapper at all std::ostream& print_hello_wrapper1(const FilestarOstream& os, int foo) { FilestarOstream& os_nc = const_cast(os); return print_hello(os_nc, foo); } // A wrapper that takes a non-const reference does not work // Boost.Python.ArgumentError ... std::ostream& print_hello_wrapper2(FilestarOstream& os, int foo) { return print_hello(os, foo); } // A wrapper that takes the a const reference to the base class, ostream, also fails // Boost.Python.ArgumentError ... std::ostream& print_hello_wrapper3(const std::ostream& os, int foo) { std::ostream& os_nc = const_cast(os); return print_hello(os_nc, foo); } // Define automatic interconversion of python file <==> FilestarOstream struct FilestarOstream_to_pyfile // untested... { static PyObject* convert(FilestarOstream& os) {return PyFile_FromFile(os.updFilestar(), "FilestarOstream", "w", NULL);} }; struct FilestarOstream_from_pyfile { FilestarOstream_from_pyfile() { bp::converter::registry::push_back( &convertible, &construct, bp::type_id()); } static void* convertible(PyObject* obj_ptr) { if( !PyFile_Check( obj_ptr ) ) {return 0;} // TODO - is there a way to check whether file is writable also? return obj_ptr; } static void construct( PyObject* obj_ptr, bp::converter::rvalue_from_python_stage1_data* data) { // TODO - the PyFile_AsFile docs say: // "If the caller will ever use the returned FILE* object while the GIL is released it must also call the PyFile_IncUseCount() and PyFile_DecUseCount() functions described below as appropriate." std::FILE* file = PyFile_AsFile(obj_ptr); typedef bp::converter::rvalue_from_python_storage filestarOstream_storage; void* const storage = reinterpret_cast(data)->storage.bytes; new (storage) FilestarOstream(file); data->convertible = storage; } }; BOOST_PYTHON_MODULE(test_mod){ // wrap std::ostream, so python will know how to convert FilestarOstream to ostream bp::class_< std::ostream, boost::noncopyable >( "std_ostream", bp::no_init ); { //::FilestarOstream typedef bp::class_< FilestarOstream, bp::bases< std::ostream >, boost::noncopyable > FilestarOstream_exposer_t; FilestarOstream_exposer_t FilestarOstream_exposer = FilestarOstream_exposer_t( "FilestarOstream", bp::init< std::FILE * >(( bp::arg("fp") )) ); bp::scope FilestarOstream_scope( FilestarOstream_exposer ); FilestarOstream_exposer.def( bp::init< >() ); } // wrap print_hello, using one of those wrappers defined above bp::def( "print_hello", // choose your wrapper // &print_hello, // no wrapper at all, Boost.Python.ArgumentError &print_hello_wrapper1, // OK // &print_hello_wrapper2, // non-const arg => Boost.Python.ArgumentError // &print_hello_wrapper3, // base class arg => Boost.Python.ArgumentError ( bp::arg("os"), bp::arg("foo") ), bp::return_internal_reference<2>()); // Register conversion from python file to FilestarOstream bp::to_python_converter; FilestarOstream_from_pyfile(); } // end boost.python wrapping code ##### python test program ###### import test_mod import sys # First test using explicit FilestarOstream # succeeds with all wrappers, # including unwrapped print_hello stream1 = test_mod.FilestarOstream() test_mod.print_hello(stream1, 1) # Remaining tests that use python files # only work with wrappers that take an # argument of const FilestarOstream& stream2 = sys.stdout test_mod.print_hello(stream2, 2) stream3 = open('test.txt', "w") test_mod.print_hello(stream3, 3) stream3.close() ##### end test program #### From roman.yakovenko at gmail.com Mon Mar 29 22:31:15 2010 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Mon, 29 Mar 2010 23:31:15 +0300 Subject: [C++-sig] custom r-value converters In-Reply-To: <9857ba051003290008i75706ffdjf712cab02b011d8d@mail.gmail.com> References: <9857ba051003281808k1d4bc3b0x4d4006c04af34d05@mail.gmail.com> <9857ba051003290008i75706ffdjf712cab02b011d8d@mail.gmail.com> Message-ID: <7465b6171003291331pbffcecvffe720170e84cecb@mail.gmail.com> On Mon, Mar 29, 2010 at 10:08 AM, Nathan Stewart wrote: > Ok some follow up - I now rip through my exposed classes looking for > String_mgr typed properties to create custom get/setters for.Then, I set the > following for that property: > > for c in classes: > ??? for property in c.public_members: > ??????????? if 'CustomString' in property.decl_string: > ? ?? ?? ??????? property.set_use_make_functions( True ) > ??? ? ? ? ? ? ? property.set_getter_call_policies( property.return_by_value > ) > ??? ??? ? ?? ?? property.set_setter_call_policies( property.return_by_value ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ May be I am missing something, but (py++) variable_t class doesn't have return_by_value property. > ) > > What is generated instead looks like this > > ?????? .add_property( "name" > ??????????????????????? , bp::make_getter( &Update::name, > bp::return_internal_reference< >() ) > ??????????????????????? , bp::make_setter( &Update::name ) ) > > when I expected it to look like: > > ?????? .add_property( "name" > ??????????????????????? , bp::make_getter( &Update::name, > bp::return_by_value() ) > ??????????????????????? , bp::make_setter( &Update::namem > bp::return_by_value() ) ) > > It's a property, and it occurs to me that it might not be a callable object. > But I don't have one at this point - make_getter/setter is creating it. What > am I doing wrong here? I am not sure. What py++ version do you use? Can you post small and complete example, of what you are trying to do? -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From talljimbo at gmail.com Tue Mar 30 00:37:33 2010 From: talljimbo at gmail.com (Jim Bosch) Date: Mon, 29 Mar 2010 15:37:33 -0700 Subject: [C++-sig] Conversion of python files to C++ ostreams In-Reply-To: References: Message-ID: <1269902254.4817.39.camel@mu> On Mon, 2010-03-29 at 13:28 -0700, Christopher Bruns wrote: > I am trying to coax boost.python to automatically convert python files > to C++ std::ostreams, for methods that take arguments of type > "std::ostream&". I have made some progress, and I could use some > advice on how to go further. > > I created a derived class of std::ostream, called FilestarOstream, > which takes a std::FILE* as it constructor argument. Then I created a > conversion from "python file" to the FilestarOstream class. Now my > python module can automatically convert a python file to a > FilestarOstream for any method that takes a "const FilestarOstream&" > as an argument. Ideally I would prefer to automatically convert a > python file for any method that takes a (non-const) "std::ostream&" as > an argument. > > I have included my simplified source code below > > My questions: > > 1 - Is there an easier way to do this? Does boost.python have a > built in incantation for wrapping methods that take a std::ostream > reference, to take python files? > Nope. > 2 - Is there a way to make the type conversion work for non-const > reference arguments? (see print_hello_wrapper2() below) > Yes, but it's a bit painful (at least the way I know how to do it). You have to make your "FilestarOstream" class a Boost.Python "object manager". That means it should probably derive publicly from boost::python::object, and you'll have to specialize a few traits classes. For an example, you can look at the Boost.Python source, or some numpy-based object managers I've thrown together here: https://svn.boost.org/trac/boost/browser/sandbox/numpy Making a class that derives publicly from both std::ostream and boost::python::object may cause some problems, however, as they're not exactly small classes. I'm not sure inheritance from object is necessary. There's apparently some distinction between the ObjectWrapper concept in the documentation: http://www.boost.org/doc/libs/1_42_0/libs/python/doc/v2/ObjectWrapper.html#ObjectWrapper-concept and the "object_manager" traits classes I discovered in the code. I'd be curious to hear if you figure any of that out. > 3 - Why does my print_hello_wrapper3() not work? It takes a const > std::ostream reference argument. I can pass it a FileStarOstream, so > python knows how to convert a FileStarOstream to a std::ostream. Plus > python knows how to convert a python file to a const FileStarOstream > reference. So why can't it convert a python file to a const ostream > reference? > Because you haven't registered a converter. Wrapping a C++ class for Python does that for you, but you can also do it manually. I could tell you all about it for rvalues, and I know there's such thing as an lvalue converter (lvalue_from_pytype is one, though it doesn't do what you want), but I've never written one. But poke around in the source and google for custom lvalue converters and you may find something. I'd solve problem #2 first, though. > 4 - In my FilestarOstream_from_pyfile::convertible method, is there > a way to check that the object is not only a file, but that it is also > writable? I suspect you really want to just throw an exception when you encounter a non-writeable file, and you could probably do that in the FilestarOstream constructor by setting a Python exception and calling boost::python::throw_error_already_set(). Having overload support for writeable vs. non-writeable file objects would probably be harder, but probably still possible (somewhere in how you implement the lvalue conversion, if it's anything like rvalue conversion). > > 5 - The PyFile_AsFile docs say "If the caller will ever use the > returned FILE* object while the GIL is released it must also call the > PyFile_IncUseCount() and PyFile_DecUseCount() functions described > below as appropriate." What is "the GIL". If I call > PyFile_IncUseCount() when I construct the FileStarOstream, when would > I call the corresponding PyFile_DecUseCount()? GIL is the global interpreter lock. You only need to worry about it if your program is multithreaded on the C++ side. In this case, if you make the FileStarOstream an object manager, it will have to own a reference to the actual underlying Python file object, and I *think* that will deal with the use count issues for you. Good luck! Jim Bosch From micdestefano at gmail.com Tue Mar 30 09:02:16 2010 From: micdestefano at gmail.com (Michele De Stefano) Date: Tue, 30 Mar 2010 09:02:16 +0200 Subject: [C++-sig] Conversion of python files to C++ ostreams In-Reply-To: References: Message-ID: Christopher, there is a much easier way to treat a FILE* as a C++ stream. The easy way is to use my open source library (mds-utils, http://code.google.com/p/mds-utils/). I have easy ways to do what you want both from C++ (i.e. treating a FILE* as a C++ std::stream) and from Python (treating Python file objects as C++ streams). Have a look at it. Unfortunately, I had not the time until now to build wiki pages, but the library comes with doxygen documentation, so, if you download it and build the doxygen, you'll have the complete API. Furthermore, there is a usage example for each class/function. I think it will really solve all your problems. Best regards. Michele De Stefano 2010/3/29 Christopher Bruns : > I am trying to coax boost.python to automatically convert python files > to C++ std::ostreams, for methods that take arguments of type > "std::ostream&". ?I have made some progress, and I could use some > advice on how to go further. > > I created a derived class of std::ostream, called FilestarOstream, > which takes a std::FILE* as it constructor argument. ?Then I created a > conversion from "python file" to the FilestarOstream class. ?Now my > python module can automatically convert a python file to a > FilestarOstream for any method that takes a "const FilestarOstream&" > as an argument. ?Ideally I would prefer to automatically convert a > python file for any method that takes a (non-const) "std::ostream&" as > an argument. > > I have included my simplified source code below > > My questions: > > ?1 - Is there an easier way to do this? ?Does boost.python have a > built in incantation for wrapping methods that take a std::ostream > reference, to take python files? > > ?2 - Is there a way to make the type conversion work for non-const > reference arguments? ?(see print_hello_wrapper2() below) > > ?3 - Why does my print_hello_wrapper3() not work? ?It takes a const > std::ostream reference argument. ?I can pass it a FileStarOstream, so > python knows how to convert a FileStarOstream to a std::ostream. ?Plus > python knows how to convert a python file to a const FileStarOstream > reference. ?So why can't it convert a python file to a const ostream > reference? > > ?4 - In my FilestarOstream_from_pyfile::convertible method, is there > a way to check that the object is not only a file, but that it is also > writable? > > ?5 - The PyFile_AsFile docs say "If the caller will ever use the > returned FILE* object while the GIL is released it must also call the > PyFile_IncUseCount() ?and PyFile_DecUseCount() ?functions described > below as appropriate." ?What is "the GIL". ?If I call > PyFile_IncUseCount() when I construct the FileStarOstream, when would > I call the corresponding PyFile_DecUseCount()? > > Thanks in advance for any helpful tips. > > ################## > //// begin test.hpp //////// > #ifndef TEST_API_PYFILE_OSTREAM_H_ > #define TEST_API_PYFILE_OSTREAM_H_ > > #include > > // ?This is the sort of method I wish to wrap > std::ostream& print_hello(std::ostream& os, int foo); > > // FilestarOstream is intended to aid python wrapping of methods that > // take ostream& args by converting an opaque C++ FILE* to a C++ ostream. > // This is just one part of the (yet unproven) task of automatically > // wrapping methods that take an ostream& as an argument. > class FilestarOstream : public std::ostream > { > public: > ? ?// std::ostreams can be constructed using an std::streambuf > ? ?// so the first step is to construct a specialized std::streambuf > ? ?// based on a FILE* > ? ?// Adapted from > ? ?// ?http://mail.python.org/pipermail/cplusplus-sig/2002-June/000896.html > ? ?class std_obuf: public std::streambuf > ? ?{ > ? ?public: > ? ? ? ?std_obuf(std::FILE* file): m_file(file) {} > ? ? ? ?std::FILE* updFilestar() {return m_file;} > ? ?protected: > ? ? ? ?std::streambuf::int_type overflow(std::streambuf::int_type c) { > ? ? ? ? ? ?return std::fputc(c, m_file) == EOF ? > std::streambuf::traits_type::eof() : c; > ? ? ? ?} > ? ? ? ?std::FILE* m_file; > ? ?}; > > ? ?FilestarOstream(std::FILE* fp) > ? ? ? ?: buf(fp), std::ostream(&buf) {} > > ? ?// Default constructor uses stdout > ? ?FilestarOstream() > ? ? ? ?: buf(stdout), std::ostream(&buf) {} > > ? ?std::FILE* updFilestar() {return buf.updFilestar();} > > protected: > ? ?std_obuf buf; > }; > > #endif // TEST_API_PYFILE_OSTREAM_H_ > //////////// end test.hpp ////////// > > > ################### > //// test.cpp /// > #include "test.hpp" > > std::ostream& print_hello(std::ostream& os, int foo) { > ? ?os << "Hello, foo = " << foo << std::endl; > ? ?return os; > } > /// end test.cpp /// > > > ###################### > // boost.python wrapping code > #include "boost/python.hpp" > #include "test.hpp" > > namespace bp = boost::python; > > // Three ways of wrapping print_hello() to take a python file argument, > // only one of which works: > > // print_hello_wrapper1() works, but I wish I did not need a wrapper at all > std::ostream& print_hello_wrapper1(const FilestarOstream& os, int foo) { > ? ?FilestarOstream& os_nc = const_cast(os); > ? ?return print_hello(os_nc, foo); > } > // A wrapper that takes a non-const reference does not work > // Boost.Python.ArgumentError ... > std::ostream& print_hello_wrapper2(FilestarOstream& os, int foo) { > ? ?return print_hello(os, foo); > } > // A wrapper that takes the a const reference to the base class, > ostream, also fails > // Boost.Python.ArgumentError ... > std::ostream& print_hello_wrapper3(const std::ostream& os, int foo) { > ? ?std::ostream& os_nc = const_cast(os); > ? ?return print_hello(os_nc, foo); > } > > // Define automatic interconversion of python file <==> FilestarOstream > struct FilestarOstream_to_pyfile // untested... > { > ? ?static PyObject* convert(FilestarOstream& os) > ? ?{return PyFile_FromFile(os.updFilestar(), "FilestarOstream", "w", NULL);} > }; > struct FilestarOstream_from_pyfile > { > ? ?FilestarOstream_from_pyfile() { > ? ? ? ?bp::converter::registry::push_back( > ? ? ? ? ? ?&convertible, &construct, bp::type_id()); > ? ?} > > ? ?static void* convertible(PyObject* obj_ptr) > ? ?{ > ? ? ? ?if( !PyFile_Check( obj_ptr ) ) {return 0;} > ? ? ? ?// TODO - is there a way to check whether file is writable also? > ? ? ? ?return obj_ptr; > ? ?} > > ? ?static void construct( > ? ? ? ? ? ?PyObject* obj_ptr, > ? ? ? ? ? ?bp::converter::rvalue_from_python_stage1_data* data) > ? ?{ > ? ? ? ?// TODO - the PyFile_AsFile docs say: > ? ? ? ?// "If the caller will ever use the returned FILE* object > while the GIL is released it must also call the PyFile_IncUseCount() > and PyFile_DecUseCount() ?functions described below as appropriate." > ? ? ? ?std::FILE* file = PyFile_AsFile(obj_ptr); > ? ? ? ?typedef > bp::converter::rvalue_from_python_storage > filestarOstream_storage; > ? ? ? ?void* const storage = > reinterpret_cast(data)->storage.bytes; > ? ? ? ?new (storage) FilestarOstream(file); > ? ? ? ?data->convertible = storage; > ? ?} > }; > > BOOST_PYTHON_MODULE(test_mod){ > ? ?// wrap std::ostream, so python will know how to convert > FilestarOstream to ostream > ? ?bp::class_< std::ostream, boost::noncopyable >( "std_ostream", > bp::no_init ); > > ? ?{ //::FilestarOstream > ? ? ? ?typedef bp::class_< FilestarOstream, bp::bases< std::ostream >>, boost::noncopyable > FilestarOstream_exposer_t; > ? ? ? ?FilestarOstream_exposer_t FilestarOstream_exposer = > FilestarOstream_exposer_t( "FilestarOstream", bp::init< std::FILE * >>(( bp::arg("fp") )) ); > ? ? ? ?bp::scope FilestarOstream_scope( FilestarOstream_exposer ); > ? ? ? ?FilestarOstream_exposer.def( bp::init< >() ); > ? ?} > > ? ?// wrap print_hello, using one of those wrappers defined above > ? ?bp::def( > ? ? ? ?"print_hello", > ? ? ? ?// choose your wrapper > ? ? ? ? ?// &print_hello, // no wrapper at all, Boost.Python.ArgumentError > ? ? ? ? ?&print_hello_wrapper1, // OK > ? ? ? ? ?// &print_hello_wrapper2, // non-const arg => > Boost.Python.ArgumentError > ? ? ? ? ?// &print_hello_wrapper3, // base class arg => > Boost.Python.ArgumentError > ? ? ? ?( bp::arg("os"), bp::arg("foo") ), > ? ? ? ?bp::return_internal_reference<2>()); > > ? ?// Register conversion from python file to FilestarOstream > ? ?bp::to_python_converter; > ? ?FilestarOstream_from_pyfile(); > } > // end boost.python wrapping code > > ##### python test program ###### > import test_mod > import sys > > # First test using explicit FilestarOstream > # succeeds with all wrappers, > # including unwrapped print_hello > stream1 = test_mod.FilestarOstream() > test_mod.print_hello(stream1, 1) > > # Remaining tests that use python files > # only work with wrappers that take an > # argument of const FilestarOstream& > stream2 = sys.stdout > test_mod.print_hello(stream2, 2) > > stream3 = open('test.txt', "w") > test_mod.print_hello(stream3, 3) > stream3.close() > ##### end test program #### > _______________________________________________ > Cplusplus-sig mailing list > Cplusplus-sig at python.org > http://mail.python.org/mailman/listinfo/cplusplus-sig > -- Michele De Stefano http://www.linkedin.com/in/micdestefano http://code.google.com/p/mds-utils http://xoomer.virgilio.it/michele_de_stefano From swarfrat at gmail.com Tue Mar 30 16:30:45 2010 From: swarfrat at gmail.com (Nathan Stewart) Date: Tue, 30 Mar 2010 10:30:45 -0400 Subject: [C++-sig] suppressing BOOST_PYTHON_MODULE Message-ID: <9857ba051003300730x69419381m306ca628536e21fb@mail.gmail.com> Can I suppress generation of the BOOST_PYTHON_MODULE while retaining the rest of the functionality the module builder provides? -------------- next part -------------- An HTML attachment was scrubbed... URL: From seefeld at sympatico.ca Tue Mar 30 16:41:59 2010 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Tue, 30 Mar 2010 10:41:59 -0400 Subject: [C++-sig] suppressing BOOST_PYTHON_MODULE In-Reply-To: <9857ba051003300730x69419381m306ca628536e21fb@mail.gmail.com> References: <9857ba051003300730x69419381m306ca628536e21fb@mail.gmail.com> Message-ID: <4BB20DB7.70508@sympatico.ca> On 03/30/2010 10:30 AM, Nathan Stewart wrote: > Can I suppress generation of the BOOST_PYTHON_MODULE while retaining > the rest of the functionality the module builder provides? I'm not sure what you are referring to by "module builder", but all that can appear inside BOOST_PYTHON_MODULE may also appear in a proper function. Thus I assume the answer to your question is "yes". Regards, Stefan -- ...ich hab' noch einen Koffer in Berlin... From rwgk at yahoo.com Tue Mar 30 20:33:37 2010 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Tue, 30 Mar 2010 11:33:37 -0700 (PDT) Subject: [C++-sig] Conversion of python files to C++ ostreams In-Reply-To: References: Message-ID: <284121.72841.qm@web111412.mail.gq1.yahoo.com> This is used in production code: http://cctbx.svn.sourceforge.net/viewvc/cctbx/trunk/boost_adaptbx/python_streambuf.h?view=markup See also: http://cctbx.svn.sourceforge.net/viewvc/cctbx/trunk/boost_adaptbx/tests/ python_streambuf_test_ext.cpp tst_python_streambuf.py tst_stderr_stdout.py tst_stdin.py tst_stdout.py The easiest way to get everything is to download from http://cci.lbl.gov/boostbx_bundles/current/ and run e.g. perl boostbx_bundle.selfx Ideally this would be part of Boost.Python proper, as built-in converters for std::istream and std::ostream, but this would require a volunteer. Ralf