From xin at xlevus.net Thu Jul 1 08:41:51 2004 From: xin at xlevus.net (xin) Date: Wed, 30 Jun 2004 23:41:51 -0700 Subject: [C++-sig] Accessing C++ values from within Python Message-ID: Hi. I have a setup such as the following: class object { public: void doSomthingElse(); float x; float *y; Somthing SomePyScript; }; int main() { object *array = new object[10]; // size of array is only an example for (int i = 0; i < 10; i++) { array[i].y = new float[array[i]] RunPythonScript(array[i]); } return 1; } Where: - " Somting SomePyScript; " Is some reference to a python script that is affiliated with this instance of the class (varies from instance to instance) - " RunPythonScript(array[i]); " Is some method of running the python script that is affiliated with the instance array[i]. My intention is that the python scripts change values within the class 'object' e.g. The python code sets 'x' to equal 0.9. And then sets each value of y to equal a muliple of 9. (y[0] = 0, y[1] = 9, y[2] = 18, ... ,y[100] = 900 etc...) Is this at all possible? Is it possible without moving all the memory from one place, to another area accessable by both python and then back again? If so how would I go about doing it? I've tried all sorts of methods of attempting this, but have had no luck. Any help would be appreciated. Thanks. From faheem at email.unc.edu Thu Jul 1 05:43:16 2004 From: faheem at email.unc.edu (Faheem Mitha) Date: Thu, 1 Jul 2004 03:43:16 +0000 (UTC) Subject: [C++-sig] Re: compile errors with embedding example from tutorial References: <2096514e040627214639a53ca5@mail.gmail.com> <2096514e04062813561ceb1d79@mail.gmail.com> Message-ID: On Tue, 29 Jun 2004 11:51:48 -0400, David Abrahams wrote: > Faheem Mitha writes: > >> On Mon, 28 Jun 2004 15:56:13 -0500, Chad Austin wrote: >>> On Mon, 28 Jun 2004 17:48:59 +0000 (UTC), Faheem Mitha >>> wrote: >>>> >>>> On Sun, 27 Jun 2004 23:46:06 -0500, Chad Austin wrote: >> >>> Nope, sorry... I had a problem similar to that in that __builtins__ >>> wasn't getting set in my modules, but I was doing some weird stuff. >>> You may want to at least check that __builtins__ is set in your >>> script. >> >> How should I do that? I thought that >> >> handle<> main_module(borrowed( PyImport_AddModule("__main__") )); >> handle<> main_namespace(borrowed( PyModule_GetDict(main_module.get()))); >> >> should do the trick, though I don't really understand what these lines >> do. > > What specifically are you confused about? Did you check the docs? Yes. Lots. I've got multiple windows open in my (tabbed) browser) with various bits of the tutorial, the reference manual, and various googled past messages from the mailing list, and I've been looking at these all weekend. There are various things that are fuzzy, but for the moment I'd just like to concentrate on getting an example compiled and working. > I don't know why you'd do it that way when you can write: Well, this is direct from the tutorial. > object main_module(handle<>(borrowed( PyImport_AddModule("__main__")))); > object main_namespace = main_module.attr("__dict__"); > > instead. This does not compile with gcc 3.3.4 on Debian. I get the following errors: embed.cc:29: error: variable declaration is not allowed here embed.cc:30: error: request for member `attr' in `main_module', which is of non-aggregate type `boost::python::api::object ()()' error: command 'gcc' failed with exit status 1 with the code ************************************************************************* #include using namespace boost::python; void foo() { Py_Initialize(); object main_module(handle<>(borrowed (PyImport_AddModule("__main__")))); object main_namespace = main_module.attr("__dict__"); (handle<>( PyRun_String("hello = file('hello.txt', 'w')\n" "hello.write('Hello world!')\n" "hello.close()", Py_file_input, main_namespace.ptr(),main_namespace.ptr()))); Py_Finalize(); } BOOST_PYTHON_MODULE(embed) { def("foo",foo); } ************************************************************************* I thought that perhaps I had the wrong compiler flags, so I tried it with bjam and the Boost Build system, and I get the same errors. However, if I replace object main_module(handle<>(borrowed (PyImport_AddModule("__main__")))); by object main_module = object(handle<>(borrowed ( PyImport_AddModule("__main__")))); as suggested in a recent post of yours, it compiles. If this is a gcc bug, as you say, has it been reported? If you can briefly explain to me what the bug is, I'd be happy to send in a report, unless it has already been fixed in gcc 3.4. (Can anyone check this?) However, like the earlier code I was using, it fails to run. Ie. I get the following errors when I try to load the code: *************************************************************************** In [2]: embed.foo() --------------------------------------------------------------------------- NameError Traceback (most recent call last) /home/faheem/wc/corrmodel/boost/ /home/faheem/wc/corrmodel/boost/ NameError: name 'file' is not defined ***************************************************************************** It cannot find the built-in `file'. Any suggestions about what is wrong here, and how to fix it? I am keen to try and get at least some basic examples of embedding working. Can anyone reproduce this problem on Linux with gcc? Unfortunately, I have other problems with the version I compiled using Boost Build, so I can't currently test that. (Subject for another message.) I think that once I have a few examples working on Debian, I will contribute basic examples along with build instructions to the Debian package, if they will take it. It may be useful for other people. >> I wonder if the fact that I am calling the interpreter inside an >> extension module is causing any problems. > Certainly not. Calling the interpreter inside an extension module is normal. Good to know. Well, if that is not the problem, I am not sure what it could be. Please help. Faheem. From caustin at gmail.com Thu Jul 1 05:00:19 2004 From: caustin at gmail.com (Chad Austin) Date: Wed, 30 Jun 2004 22:00:19 -0500 Subject: [C++-sig] Re: Calling a python function from C++ (from Jeff Holle) In-Reply-To: References: <40E142ED.2030603@verizon.net> Message-ID: <2096514e0406302000530e12e0@mail.gmail.com> Straight from my codebase: std::string getPythonErrorString() { // Extra paranoia... if (!PyErr_Occurred()) { return "No Python error"; } PyObject *type, *value, *traceback; PyErr_Fetch(&type, &value, &traceback); PyErr_Clear(); std::string message = "Python error: "; if (type) { type = PyObject_Str(type); message += PyString_AsString(type); } if (value) { value = PyObject_Str(value); message += ": "; message += PyString_AsString(value); } Py_XDECREF(type); Py_XDECREF(value); Py_XDECREF(traceback); return message; } void checkForPythonError() { if (PyErr_Occurred()) { throw PythonError(getPythonErrorString()); } } void requirePythonError() { if (!PyErr_Occurred()) { throw PythonError("Boost.Python exception, " "but no Python error set."); } } ... PYR_DEFINE_RUNTIME_ERROR(PythonError); std::string getPythonErrorString(); void checkForPythonError(); void requirePythonError(); /** * Allows us to check for Python errors at the end of a Python * code block whether control left the end of the block or * 'return' was used. */ struct PythonCodeErrorSentry { ~PythonCodeErrorSentry() { if (!std::uncaught_exception()) { checkForPythonError(); } } }; #define PYR_NO_UNUSED_WARNING(x) ((void)&(x)) #define PYR_BEGIN_PYTHON_CODE() \ try { \ PythonCodeErrorSentry sentry__; \ PYR_NO_UNUSED_WARNING(sentry__); // silly gcc #define PYR_END_PYTHON_CODE() \ } \ catch (const boost::python::error_already_set&) { \ requirePythonError(); \ throw PythonError(getPythonErrorString()); \ } May have bugs, but it should give you an idea of what to do. Notice I don't do anything with the stacktrace object yet, but it wouldn't take much more work. HTH, Chad On Wed, 30 Jun 2004 02:39:46 -0400, Jeffrey Holle wrote: > > Given what the name of this exception, I assume there is a source of > information to obtain useful information about it. > To this end, I've dug a bit into the Python C API and found the added > the following to my code example: > > catch (error_already_set& x) { > PyObject *err_type,*err_value,*err_traceback; > PyErr_Fetch(&err_type,&err_value,&err_traceback); > cout << "something bad happened" << endl; > } > > While I see that err_type and error_value are not null pointers after > the call to PyErr_Fetch, I don't know what to do with either to get at a > useful message. > Can anybody provide any hints? > > > > Jeffrey Holle wrote: > > I've explored whats actually going on some with my debugger and now see > > what is being thrown. > > It is "error_already_set". This is a trivial object (it has no > > attributes at all), and isn't much better than "catch (...)". > > However, its name implies something. Is there a meaningful error > > message set somewhere else that can be accessed within the catch clause > > of "error_already_set"? > > > > Jeff Holle wrote: > > > >>> > >>> > >>>> An underlining concern I have is error handling. When > >>>> PyImport_ImportModule fails, a NULL pointer is returned. > >>>> Seems like the underlining machinery in "handle<>" is intolerant of > >>>> this. > >>> > >>> > >>> > >>> > >>> > >>> What makes you say that? > >>> > >> You are correct about the success in compiling your much cleaner > >> example, and it works :-) , but has a flaw. > >> > >> When I hide the needed python script, the call to > >> PyImport_ImportModule returns NULL. > >> When this occurres, both your example and what I had created, but > >> commented out throws something because I can catch it with > >> "catch(...)". I don't however know how to be more specific. Any > >> hints? Whatever it is, it doesn't inherit from "exception". > >> > >> If I was operating on windows, I would anticipate it was a "structured > >> exception", or whatever Microsoft calls their propritary stuff. Don't > >> know of the equivalent on linux though. Without the "catch (...)", > >> the command line program exits with "Aborted". > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > From gfilla at gmail.com Thu Jul 1 07:52:03 2004 From: gfilla at gmail.com (Drew Ferraro) Date: Thu, 1 Jul 2004 01:52:03 -0400 Subject: [C++-sig] please help with simple program crashing Message-ID: <352b386804063022526df14a1e@mail.gmail.com> hi, ive recently trying to add a scripting system to a game i am making.. anyway, ive started to learn python and am trying to figure out how to embed it in my game. i have gotten a C++ function to work from inside C++ but called from python via PyRun_SimpleString(),,, i can send commands directly to the intepreter with that function, but im having a problem with PyRun_SimpleFile(). im trying to execute a python script with this function, but its crashing when it gets to this line: PyRun_SimpleFile(fp,"test.py"); i cant figure out what im doing wrong. here is the source. any help is greatly appreciated!! #include #include #include using namespace std; using namespace boost::python; #ifdef _WIN32 #pragma comment(lib,"boost_python.lib"); #endif int main() { Py_Initialize(); FILE *fp = NULL; fp = fopen("test.py", "r"); if(fp == NULL) return 1; PyRun_SimpleFile(fp,"test.py"); Py_Finalize(); system("PAUSE"); return 0; } thanks for any help! also, i tried not opening the file myself, and just sending PR_SF() a NULL FILE*... it didnt crash! instead, in the console it said there was a syntax error and printed out some garbage characters... i dont think theres a syntax error, "text.py" entire file just says print "hello world" thanks again! From dave at boost-consulting.com Thu Jul 1 15:48:03 2004 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 01 Jul 2004 09:48:03 -0400 Subject: [C++-sig] Re: Calling a python function from C++ (from Jeff Holle) References: <40E142ED.2030603@verizon.net> Message-ID: Jeffrey Holle writes: > I've explored whats actually going on some with my debugger and now > see what is being thrown. > It is "error_already_set". Yes; did you miss my posting? http://article.gmane.org/gmane.comp.python.c%2B%2B/6662 -- Dave Abrahams Boost Consulting http://www.boost-consulting.com From dave at boost-consulting.com Thu Jul 1 15:49:59 2004 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 01 Jul 2004 09:49:59 -0400 Subject: [C++-sig] Re: Calling a python function from C++ (from Jeff Holle) References: <40E142ED.2030603@verizon.net> <2096514e0406302000530e12e0@mail.gmail.com> Message-ID: Chad Austin writes: > std::string getPythonErrorString(); > void checkForPythonError(); > void requirePythonError(); > > /** > * Allows us to check for Python errors at the end of a Python > * code block whether control left the end of the block or > * 'return' was used. > */ > struct PythonCodeErrorSentry { > ~PythonCodeErrorSentry() { > if (!std::uncaught_exception()) { > checkForPythonError(); > } > } > }; Watch that you don't ever destroy one of these from within a catch block (directly or indirectly), because std::uncaught_exception() will be false at that point. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com From dave at boost-consulting.com Thu Jul 1 15:52:59 2004 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 01 Jul 2004 09:52:59 -0400 Subject: [C++-sig] Re: please help with simple program crashing References: <352b386804063022526df14a1e@mail.gmail.com> Message-ID: Drew Ferraro writes: > hi, > > ive recently trying to add a scripting system to a game i am making.. > anyway, ive started to learn python and am trying to figure out how to > embed it in my game. i have gotten a C++ function to work from inside > C++ but called from python via PyRun_SimpleString(),,, i can send > commands directly to the intepreter with that function, but im having > a problem > with PyRun_SimpleFile(). im trying to execute a python script with > this function, but its crashing when it gets to this line: > > PyRun_SimpleFile(fp,"test.py"); > > i cant figure out what im doing wrong. here is the source. any help is > greatly appreciated!! One likely possibility is that your Python was built with a different C/C++ standard library than your program, so they have different ideas of what a FILE is supposed to be. Also, Boost.Python is incompatible with Py_Finalize... though it's not clear why you're linking with Boost.Python anyway, since you're not using it. > #include > #include > #include > > > using namespace std; > using namespace boost::python; > > > #ifdef _WIN32 > #pragma comment(lib,"boost_python.lib"); > #endif > > int main() > { > > Py_Initialize(); > > FILE *fp = NULL; > fp = fopen("test.py", "r"); > > if(fp == NULL) > return 1; > > PyRun_SimpleFile(fp,"test.py"); > > Py_Finalize(); > > system("PAUSE"); > > return 0; > } > > thanks for any help! also, i tried not opening the file myself, and > just sending PR_SF() a NULL FILE*... it didnt crash! instead, in the > console it said there was a syntax error and printed out some garbage > characters... i dont think theres a syntax error, "text.py" entire > file just says print "hello world" > > thanks again! -- Dave Abrahams Boost Consulting http://www.boost-consulting.com From wirawan at camelot.physics.wm.edu Thu Jul 1 17:59:56 2004 From: wirawan at camelot.physics.wm.edu (Wirawan Purwanto) Date: Thu, 1 Jul 2004 11:59:56 -0400 (EDT) Subject: [C++-sig] Problem: boost_python 1.31 (release) causes huge memory allocation Message-ID: Hi, Just a compliment, first: I am very new to boost::python library. I'm really impressed at the ease of use of that library. I have an existing code that I want to "manipulate" via python, and it only took me a few tests to get the simple interface up and running! Now is the meat. :) To highlight where the questions are, I put "QUESTION:" at the beginning of the paragraph, below. Sorry if the detail is too long. I am using Mandrake Linux 10 (kernel = 2.6.3-7mdk, gcc = 3.3.2-6mdk) and boost library version 1.31.0 (official release). I compiled the *whole* boost library using bjam, as directed in the website. The first attempt to "wrap" my code with boost::python went fine. Here's the wrapper initialization code: BOOST_PYTHON_MODULE(HubbardGP) { using namespace boost::python; TBH_PY_DEBUG(("Initializing HubbardGP module interface\n")); class_("HubbardGP") .def("OpenFiles", &HubbardGP::OpenFiles) .def("Solve", &HubbardGP::Solve) .def("ReportResults", &HubbardGP::ReportResults) // .add_property("ndim", &HubbardGP::ndim_pyget) ; TBH_PY_DEBUG(("Done initializing HubbardGP module interface\n")); } Please disregard "TBH_PY_DEBUG" there--it just calls C's printf function to print the string on the screen. I built my shared object (HubbardGP.so) using make(1) for a stupid reason: I still don't understand completely bjam's quirks. I linked against the "release" version of libboost_python-gcc.so, in this way: $ g++ -L/usr/local/lib -fPIC -Wall -ftemplate-depth-100 \ -g -O0 -DDEBUG \ -DBOOST_PYTHON_DYNAMIC_LIB \ -DTBHQMC_MAKE_BOOST_PYTHON_MODULE \ -DTBH_NDIM=1 -DTBH_USE_FFTW3 -D__section__=1 \ -Isrc -Isrc/cp.inc \ -I/usr/local/boost-1.31.0/include/boost-1_31 \ -I/usr/include/python2.3 \ -c src/test-lattice-params.cpp -o objs/HubbardGP.o $ g++ -L/usr/local/lib -shared -Wall -static-libgcc \ -llapack -lcblas -lf77blas -latlas -lfftw3 \ -lg2c \ -lboost_python-gcc \ -L/usr/local/boost-1.31.0/lib \ objs/HubbardGP.o -o HubbardGP.so Do you see the difference? My code was compiled using DEBUG switch (and -O0), but then linked to the RELEASE variant of the boost::python lib. QUESTION: is this an acceptable practice? I'm wondering if the DEBUG code must always be linked against the DEBUG boost::python lib and vice versa. QUESTION: Without the .addproperty() stuff (that's commented in the snippet above), the code runs fine. But when I added the .addproperty() line, a calamity happens: when I was about to instantiate HubbardGP object, the computer froze. When I checked using top(1), the python program tries to allocate a huge chunk of memory, which did NOT happen before the .addproperty() is added in my wrapper. I re-ran strace(1), and found that the program (either python or the boost_python lib, or remotely possibly my own code?) attempted to allocate ~590MB of memory. Here's the strace(1) output, when I forcibly LIMIT the amount of vmem available to the program to 250 MB only: [del] write(1, "Initializing HubbardGP module in"..., 40Initializing HubbardGP module interface) = 40 write(1, "Done initializing HubbardGP modu"..., 45Done initializing HubbardGP module interface) = 45 close(3) = 0 futex(0x804a998, FUTEX_WAKE, 1) = 0 write(1, "Creating an instance of HubbardG"..., 34Creating an instance of HubbardGP) = 34 > mmap2(NULL, 595271680, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, > 0) = -1 ENOMEM (Cannot allocate memory) brk(0) = 0x80d6000 brk(0x2b888000) = 0x80d6000 > mmap2(NULL, 595406848, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, > 0) = -1 ENOMEM (Cannot allocate memory) mmap2(NULL, 2097152, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x87cb5000 munmap(0x87cb5000, 307200) = 0 munmap(0x87e00000, 741376) = 0 mprotect(0x87d00000, 135168, PROT_READ|PROT_WRITE) = 0 > mmap2(NULL, 595271680, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, > 0) = -1 ENOMEM (Cannot allocate memory) futex(0x401edaf4, FUTEX_WAKE, 2147483647) = 0 futex(0x402207d4, FUTEX_WAKE, 2147483647) = 0 write(2, "Traceback (most recent call last"..., 35Traceback (most recent call last):) = 35 open("test-lattice-params.py", O_RDONLY|O_LARGEFILE) = 3 write(2, " File \"test-lattice-params.py\","..., 46 File "test-lattice-params.py", line 4, in ?) = 46 fstat64(3, {st_mode=S_IFREG|0644, st_size=267, ...}) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xab5b2000 read(3, "import HubbardGP\n\nprint \"Creatin"..., 4096) = 267 write(2, " ", 4 ) = 4 write(2, "H = HubbardGP.HubbardGP()\n", 26H = HubbardGP.HubbardGP() ) = 26 close(3) = 0 munmap(0xab5b2000, 4096) = 0 write(2, "MemoryError", 11MemoryError) = 11 write(2, "\n", 1 ) = 1 [del] There are 3 points when it tries to allocate huge amount of memory. Now, I'm too new to both python and boost::python. Could you help me with this? I don't believe that my code was the one doing the mess. I tend to think that somehow the compiled boost_python code was acting up here. But I can't debug the code easily, as it involves running python itself in the debugger. How do you debug such a problem? Using python debugger is also not possible, since I don't think it allows going down to the C++-level code. As a workaround, I could only link my HubbardGP.so against the DEBUG variant (libboost_python-gcc-d.so). Then the code went fine, even with .add_property() there. I tried once to regenerate the problem using a much smaller testcase, but the problem (huge mmap2) didn't show up. As a reference, here's my python test code: import HubbardGP print "Creating an instance of HubbardGP" H = HubbardGP.HubbardGP() print "Done, now opening files" x = H.OpenFiles("/tmp/file1.txt", "/tmp/file2.txt", "/tmp/file3.txt") print "x is %d" % x H.Solve() print "NOW REPORTING RESULTS:" H.ReportResults() I would appreciate if someone helps me out in this respect. The full source code of the wrapped C++ object is available if you need to look into it. But it's way too large to post here. Thanks, Wirawan From graeme.lufkin at gmail.com Thu Jul 1 18:05:32 2004 From: graeme.lufkin at gmail.com (Graeme Lufkin) Date: Thu, 1 Jul 2004 09:05:32 -0700 Subject: [C++-sig] Re: compile errors with embedding example from tutorial In-Reply-To: References: <2096514e040627214639a53ca5@mail.gmail.com> <2096514e04062813561ceb1d79@mail.gmail.com> Message-ID: <4d3b9ecb04070109051b127d80@mail.gmail.com> I've had similar problems, and have slogged my way to figuring them out. The tutorial is wrong, at least on gcc 3.2.3. Here's what you want: After calling Py_Initialize(), you should get the Python main namespace object by doing: handle<> main_module(borrowed( PyImport_AddModule("__main__") )); dict main_namespace = extract(PyModule_GetDict(main_module.get())); The first line gets a pointer to the '__main__' module object and stores it as a borrowed reference in a handle. The second line gets the dictionary of the '__main__' module and puts it in a dict C++ object. You should now use this dictionary as the globals and locals of PyRun_* functions that you call. For example: handle<> unused(PyRun_String("import yourModuleNameHere", Py_file_input, main_namespace.ptr(), main_namespace.ptr())); handle<> unused2(PyRun_String("f = file('test_output', 'w')", Py_file_input, main_namespace.ptr(), main_namespace.ptr())); You need to name the handle<> objects, even though you don't use them. If not, while you may think you're creating an anonymous temporary that will immediately get destructed, the compiler thinks you're declaring a function and gets very confused. Hope this helps. As usual, I invoke the great spirit of Dave Abrahams to correct/clarify anything I've said that's not quite right or misleading. Good luck -- -- Graeme graeme.lufkin at gmail.com From dave at boost-consulting.com Thu Jul 1 18:56:59 2004 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 01 Jul 2004 12:56:59 -0400 Subject: [C++-sig] Re: Problem: boost_python 1.31 (release) causes huge memory allocation References: Message-ID: Wirawan Purwanto writes: > Hi, > > Just a compliment, first: I am very new to boost::python library. I'm > really impressed at the ease of use of that library. I have an > existing code that I want to "manipulate" via python, and it only took > me a few tests to get the simple interface up and running! Thanks! > I built my shared object (HubbardGP.so) using make(1) for a stupid > reason: I still don't understand completely bjam's quirks. I linked > against the "release" version of libboost_python-gcc.so, in this way: > > $ g++ -L/usr/local/lib -fPIC -Wall -ftemplate-depth-100 \ > -g -O0 -DDEBUG \ > -DBOOST_PYTHON_DYNAMIC_LIB \ > -DTBHQMC_MAKE_BOOST_PYTHON_MODULE \ > -DTBH_NDIM=1 -DTBH_USE_FFTW3 -D__section__=1 \ > -Isrc -Isrc/cp.inc \ > -I/usr/local/boost-1.31.0/include/boost-1_31 \ > -I/usr/include/python2.3 \ > -c src/test-lattice-params.cpp -o objs/HubbardGP.o > > $ g++ -L/usr/local/lib -shared -Wall -static-libgcc \ > -llapack -lcblas -lf77blas -latlas -lfftw3 \ > -lg2c \ > -lboost_python-gcc \ > -L/usr/local/boost-1.31.0/lib \ > objs/HubbardGP.o -o HubbardGP.so > > Do you see the difference? My code was compiled using DEBUG switch > (and -O0), but then linked to the RELEASE variant of the boost::python > lib. > > QUESTION: is this an acceptable practice? I'm wondering if the DEBUG > code must always be linked against the DEBUG boost::python lib and > vice versa. The preprocessor symbol "DEBUG" means nothing to Boost.Python one way or the other. To get the right compilation/link command lines, build the example projects using bjam -d+2 or just trial-run the build with bjam -n -a and copy those down. I can't vouch for your bulid being correct otherwise. > QUESTION: Without the .addproperty() stuff (that's commented in the > snippet above), the code runs fine. But when I added the > .addproperty() line, a calamity happens: when I was about to > instantiate HubbardGP object, the computer froze. > Now, I'm too new to both python and boost::python. Could you help me > with this? I have no clue. > I don't believe that my code was the one doing the mess. I > tend to think that somehow the compiled boost_python code was acting > up here. Always blame the other guy ;-) > But I can't debug the code easily, as it involves running > python itself in the debugger. How do you debug such a problem? I run Python itself in the debugger. What's so hard about that? > Using python debugger is also not possible, since I don't think it > allows going down to the C++-level code. > > As a workaround, I could only link my HubbardGP.so against the DEBUG > variant (libboost_python-gcc-d.so). Then the code went fine, even with > .add_property() there. Sounds like you got your build commands wrong. Never fails. Use bjam first, then once you get that right, you can do whatever you want. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com From dave at boost-consulting.com Thu Jul 1 18:50:45 2004 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 01 Jul 2004 12:50:45 -0400 Subject: [C++-sig] Re: compile errors with embedding example from tutorial References: <2096514e040627214639a53ca5@mail.gmail.com> <2096514e04062813561ceb1d79@mail.gmail.com> <4d3b9ecb04070109051b127d80@mail.gmail.com> Message-ID: Graeme Lufkin writes: > I've had similar problems, and have slogged my way to figuring > them out. The tutorial is wrong, at least on gcc 3.2.3. I think the tutorial is right in CVS. Have you checked that? http://www.boost-consulting.com/boost/libs/python/ > Here's what you want: After calling Py_Initialize(), you should get > the Python main namespace object by doing: > > handle<> main_module(borrowed( PyImport_AddModule("__main__") )); > dict main_namespace = extract(PyModule_GetDict(main_module.get())); Seems harder than neccessary. object main_module = object(handle<> (borrowed( PyImport_AddModule("__main__") ))); object main_namespace = main_module.attr("__dict__"); -- Dave Abrahams Boost Consulting http://www.boost-consulting.com From gfilla at gmail.com Thu Jul 1 19:17:54 2004 From: gfilla at gmail.com (Drew Ferraro) Date: Thu, 1 Jul 2004 13:17:54 -0400 Subject: [C++-sig] Re: please help with simple program crashing In-Reply-To: References: <352b386804063022526df14a1e@mail.gmail.com> Message-ID: <352b386804070110177d50d3a7@mail.gmail.com> hi dave, thanks for your reply! this might sound stupid, but could you tell me what i should do then to have them both use the same standard library? im using visual studio .net 2003 if that matters. also, what is the alternative to Py_Finalize, and why is it incompatible but the other Py_XXX function are not ? thanks for any help! ps, i have boost included because i was just using it to do some other stuff (i was actually able to call a C++ function through the Py_SimpleString() function...) On Thu, 01 Jul 2004 09:52:59 -0400, David Abrahams wrote: > > Drew Ferraro writes: > > > hi, > > > > ive recently trying to add a scripting system to a game i am making.. > > anyway, ive started to learn python and am trying to figure out how to > > embed it in my game. i have gotten a C++ function to work from inside > > C++ but called from python via PyRun_SimpleString(),,, i can send > > commands directly to the intepreter with that function, but im having > > a problem > > with PyRun_SimpleFile(). im trying to execute a python script with > > this function, but its crashing when it gets to this line: > > > > PyRun_SimpleFile(fp,"test.py"); > > > > i cant figure out what im doing wrong. here is the source. any help is > > greatly appreciated!! > > One likely possibility is that your Python was built with a different > C/C++ standard library than your program, so they have different > ideas of what a FILE is supposed to be. Also, Boost.Python is > incompatible with Py_Finalize... though it's not clear why you're > linking with Boost.Python anyway, since you're not using it. > > > #include > > #include > > #include > > > > > > using namespace std; > > using namespace boost::python; > > > > > > #ifdef _WIN32 > > #pragma comment(lib,"boost_python.lib"); > > #endif > > > > int main() > > { > > > > Py_Initialize(); > > > > FILE *fp = NULL; > > fp = fopen("test.py", "r"); > > > > if(fp == NULL) > > return 1; > > > > PyRun_SimpleFile(fp,"test.py"); > > > > Py_Finalize(); > > > > system("PAUSE"); > > > > return 0; > > } > > > > thanks for any help! also, i tried not opening the file myself, and > > just sending PR_SF() a NULL FILE*... it didnt crash! instead, in the > > console it said there was a syntax error and printed out some garbage > > characters... i dont think theres a syntax error, "text.py" entire > > file just says print "hello world" > > > > thanks again! > > -- > Dave Abrahams > Boost Consulting > http://www.boost-consulting.com > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > From jeff.holle at verizon.net Thu Jul 1 05:36:21 2004 From: jeff.holle at verizon.net (Jeffrey Holle) Date: Wed, 30 Jun 2004 23:36:21 -0400 Subject: [C++-sig] boost::python embedding error handling Message-ID: The good news is that now I can get useful error messages from boost::python, I'm more than willing to use it. Its a keeper! I would like to provide some critism of the boost::python::error_already_set exceptions. 1. It doesn't inherit from std::exception. 2. It provides no information. On the other hand, its concept of obtaining error information from the python interpreter is soundly a good idea. Its just isn't finished. I've written what I would consider a replacement for it and attached it. Note that the code it its constuctor is pretty much what Chad Austin contributed to this news group. Thanks. To use it, I will need to place a try clause around all boost::python embedding code with the following catch clause: catch (error_already_set&) { throw python_error(); } I consider this acceptable, but it would be better to not need it. In critism of python_error: 1. It inherits from std::runtime_error. It can be argued, I think, that it should be std::exception instead. Becaue std::runtime_error doesn't provide protected access to its string attribute, I've had to provide one in python_error. This means there is need for a "what" method implementation and that runtime_error's attribute is wasted bagage. 2. It arguably does too much in its constructor. This is a convenence issue for me. Constructed at a lower level, it could easily be changed. 3. Chad's code assumes that the python objects returned from PyErr_Fetch are strings. I do not know if this assumption is safe. I've seen code on the web that does not make it. 4. As Chad indicated, his code presently doesn't handle the traceback info. I plan to add this to python_error as a seperate attribute and accessor, eventually ... -------------- next part -------------- A non-text attachment was scrubbed... Name: python_error.cpp Type: text/x-c++ Size: 832 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: python_error.h Type: text/x-c-header Size: 428 bytes Desc: not available URL: From faheem at email.unc.edu Thu Jul 1 22:19:37 2004 From: faheem at email.unc.edu (Faheem Mitha) Date: Thu, 1 Jul 2004 20:19:37 +0000 (UTC) Subject: [C++-sig] Re: compile errors with embedding example from tutorial References: <2096514e040627214639a53ca5@mail.gmail.com> <2096514e04062813561ceb1d79@mail.gmail.com> <4d3b9ecb04070109051b127d80@mail.gmail.com> Message-ID: On Thu, 1 Jul 2004 09:05:32 -0700, Graeme Lufkin wrote: > I've had similar problems, and have slogged my way to figuring > them out. The tutorial is wrong, at least on gcc 3.2.3. > Here's what you want: After calling Py_Initialize(), you should get > the Python main namespace object by doing: > > handle<> main_module(borrowed( PyImport_AddModule("__main__") )); > dict main_namespace = extract(PyModule_GetDict(main_module.get())); I think this should be main_module.ptr() since main_module is an object. > The first line gets a pointer to the '__main__' module object and > stores it as a borrowed reference in a handle. The second line gets > the dictionary of the '__main__' module and puts it in a dict C++ > object. You should now use this dictionary as the globals and locals > of PyRun_* functions that you call. For example: > handle<> unused(PyRun_String("import yourModuleNameHere", > Py_file_input, main_namespace.ptr(), main_namespace.ptr())); > handle<> unused2(PyRun_String("f = file('test_output', 'w')", > Py_file_input, main_namespace.ptr(), main_namespace.ptr())); > > You need to name the handle<> objects, even though you don't use them. > If not, while you may think you're creating an anonymous temporary > that will immediately get destructed, the compiler thinks you're > declaring a function and gets very confused. > > Hope this helps. As usual, I invoke the great spirit of Dave Abrahams > to correct/clarify anything I've said that's not quite right or > misleading. Good luck I'm trying with ****************************************************************************** #include using namespace boost::python; void foo() { Py_Initialize(); object main_module = object(handle<>(borrowed(PyImport_AddModule("__main__")))); dict main_namespace = extract(PyModule_GetDict(main_module.ptr())); handle<> unused(PyRun_String("hello = file('hello.txt', 'w')\n" "hello.write('Hello world!')\n" "hello.close()", Py_file_input, main_namespace.ptr(),main_namespace.ptr())); Py_Finalize(); } BOOST_PYTHON_MODULE(embed) { def("foo",foo); } ******************************************************************************* This compiles, but I get the same error as before, namely NameError: name 'file' is not defined Does this work correctly for you? I'm wondering if there is some issue with my compiler flags. I'm trying to get Boost.Build to work but there are some linking problems. Faheem. From faheem at email.unc.edu Thu Jul 1 22:34:49 2004 From: faheem at email.unc.edu (Faheem Mitha) Date: Thu, 1 Jul 2004 20:34:49 +0000 (UTC) Subject: [C++-sig] Re: compile errors with embedding example from tutorial References: <2096514e040627214639a53ca5@mail.gmail.com> <2096514e04062813561ceb1d79@mail.gmail.com> <4d3b9ecb04070109051b127d80@mail.gmail.com> Message-ID: On Thu, 01 Jul 2004 12:50:45 -0400, David Abrahams wrote: > Graeme Lufkin writes: > >> I've had similar problems, and have slogged my way to figuring >> them out. The tutorial is wrong, at least on gcc 3.2.3. > > I think the tutorial is right in CVS. Have you checked that? > > http://www.boost-consulting.com/boost/libs/python/ > >> Here's what you want: After calling Py_Initialize(), you should get >> the Python main namespace object by doing: >> >> handle<> main_module(borrowed( PyImport_AddModule("__main__") )); >> dict main_namespace = extract(PyModule_GetDict(main_module.get())); > > Seems harder than neccessary. > > object main_module = object(handle<> (borrowed( > PyImport_AddModule("__main__") ))); > > object main_namespace = main_module.attr("__dict__"); http://www.boost-consulting.com/boost/libs/python/doc/tutorial/doc /using_the_interpreter.html uses object main_module( handle<>(borrowed(PyImport_AddModule("__main__")))); instead, which does not compile with gcc 3.3, at least for me. In any case, as I already said, even when this compiles correctly, it still does not seem to execute the interpreter correctly, ie. I get the error NameError: name 'file' is not defined Can you suggest what might be the problem here? Faheem. From graeme.lufkin at gmail.com Thu Jul 1 22:52:17 2004 From: graeme.lufkin at gmail.com (Graeme Lufkin) Date: Thu, 1 Jul 2004 13:52:17 -0700 Subject: [C++-sig] Re: compile errors with embedding example from tutorial In-Reply-To: References: <2096514e040627214639a53ca5@mail.gmail.com> <2096514e04062813561ceb1d79@mail.gmail.com> <4d3b9ecb04070109051b127d80@mail.gmail.com> Message-ID: <4d3b9ecb0407011352f11f078@mail.gmail.com> On Thu, 1 Jul 2004 20:19:37 +0000 (UTC), Faheem Mitha wrote: > > > I've had similar problems, and have slogged my way to figuring > > them out. The tutorial is wrong, at least on gcc 3.2.3. > > Here's what you want: After calling Py_Initialize(), you should get > > the Python main namespace object by doing: > > > > handle<> main_module(borrowed( PyImport_AddModule("__main__") )); > > dict main_namespace = extract(PyModule_GetDict(main_module.get())); > > I think this should be main_module.ptr() since main_module is an object. In my example it's a handle<>, so get() is correct. In Dave's (and your) examples, it's an object, so ptr() is correct. > I'm trying with > > ****************************************************************************** > #include > using namespace boost::python; > > void foo() > { > Py_Initialize(); > > object main_module = > object(handle<>(borrowed(PyImport_AddModule("__main__")))); > > dict main_namespace = extract(PyModule_GetDict(main_module.ptr())); > > handle<> unused(PyRun_String("hello = file('hello.txt', 'w')\n" > "hello.write('Hello world!')\n" > "hello.close()", Py_file_input, > main_namespace.ptr(),main_namespace.ptr())); > Py_Finalize(); > } > > BOOST_PYTHON_MODULE(embed) > { > def("foo",foo); > } > ******************************************************************************* > > This compiles, but I get the same error as before, namely > > NameError: name 'file' is not defined > > Does this work correctly for you? I'm wondering if there is some issue > with my compiler flags. I'm trying to get Boost.Build to work but > there are some linking problems. First, your extension module should never call Py_Initialize() or Py_Finalize(), as Python will already be initialized by the time you're running methods in it. I think what you want is foo() to be main(), with no extension module stuff needed. Also, Boost.Python and Py_Finalize() don't play nice, so never call it (check the list archive for details, I don't really understand why myself). Second, yes this compiles and runs correctly for me, after removing the Py_Initialize and Py_Finalize calls. Third, you definitely need to use Boost.Build for a few sample programs before you think about switching back to Makefiles. I share your frustration at Boost.Build sometimes, but it does a particular job admirably. I submitted some patches to the docs and the Jamfile rules a while ago that were aimed at making it easier to use Boost.Build for extensions and embedded apps. Dave hasn't gotten back to me yet. (Hint hint) -- -- Graeme graeme.lufkin at gmail.com From faheem at email.unc.edu Fri Jul 2 00:48:24 2004 From: faheem at email.unc.edu (Faheem Mitha) Date: Thu, 1 Jul 2004 22:48:24 +0000 (UTC) Subject: [C++-sig] Re: compile errors with embedding example from tutorial References: <2096514e040627214639a53ca5@mail.gmail.com> <2096514e04062813561ceb1d79@mail.gmail.com> <4d3b9ecb04070109051b127d80@mail.gmail.com> <4d3b9ecb0407011352f11f078@mail.gmail.com> Message-ID: On Thu, 1 Jul 2004 13:52:17 -0700, Graeme Lufkin wrote: > On Thu, 1 Jul 2004 20:19:37 +0000 (UTC), Faheem Mitha > wrote: >> >> > I've had similar problems, and have slogged my way to figuring >> > them out. The tutorial is wrong, at least on gcc 3.2.3. >> > Here's what you want: After calling Py_Initialize(), you should get >> > the Python main namespace object by doing: >> > >> > handle<> main_module(borrowed( PyImport_AddModule("__main__") )); >> > dict main_namespace = extract(PyModule_GetDict(main_module.get())); >> >> I think this should be main_module.ptr() since main_module is an object. > > In my example it's a handle<>, so get() is correct. In Dave's (and > your) examples, it's an object, so ptr() is correct. Ok. Sorry. I stand corrected. >> I'm trying with >> >> ****************************************************************************** >> #include >> using namespace boost::python; >> >> void foo() >> { >> Py_Initialize(); >> >> object main_module = >> object(handle<>(borrowed(PyImport_AddModule("__main__")))); >> >> dict main_namespace = extract(PyModule_GetDict(main_module.ptr())); >> >> handle<> unused(PyRun_String("hello = file('hello.txt', 'w')\n" >> "hello.write('Hello world!')\n" >> "hello.close()", Py_file_input, >> main_namespace.ptr(),main_namespace.ptr())); >> Py_Finalize(); >> } >> >> BOOST_PYTHON_MODULE(embed) >> { >> def("foo",foo); >> } >> ******************************************************************************* >> >> This compiles, but I get the same error as before, namely >> >> NameError: name 'file' is not defined >> >> Does this work correctly for you? I'm wondering if there is some issue >> with my compiler flags. I'm trying to get Boost.Build to work but >> there are some linking problems. > > First, your extension module should never call Py_Initialize() or > Py_Finalize(), as Python will already be initialized by the time > you're running methods in it. I think what you want is foo() to be > main(), with no extension module stuff needed. Also, Boost.Python and > Py_Finalize() don't play nice, so never call it (check the list > archive for details, I don't really understand why myself). > Second, yes this compiles and runs correctly for me, after removing > the Py_Initialize and Py_Finalize calls. Just to make sure we are on the same page here. I want to run the interpreter inside an extension module. In other words, I want an extension module called embed.so, not an executable called embed. > Third, you definitely need to use Boost.Build for a few sample > programs before you think about switching back to Makefiles. I share > your frustration at Boost.Build sometimes, but it does a particular > job admirably. I submitted some patches to the docs and the Jamfile > rules a while ago that were aimed at making it easier to use > Boost.Build for extensions and embedded apps. Dave hasn't gotten back > to me yet. (Hint hint) Up to now I had been using distutils for extension modules, which has worked fine for examples which don't embed the interpreter. It doesn't seem to be working for this example, though. I've been trying to use Boost.Build for this example. I added a section to libs/python/example/Jamfile as follows. ******************************************************************* # ----- embed ------- # Declare a Python extension called embed extension embed : # sources embed.cc # requirements and dependencies for Boost.Python extensions