diff --git a/doc/v2/faq.html b/doc/v2/faq.html index 06087038..1b600072 100644 --- a/doc/v2/faq.html +++ b/doc/v2/faq.html @@ -29,10 +29,10 @@
-
Is return_internal reference +
Is return_internal_reference efficient?
-
How can I wrap containers which take C++ +
How can I wrap functions which take C++ containers as arguments?
fatal error C1204:Compiler limit:internal @@ -40,13 +40,18 @@
How do I debug my Python extensions?
-
Why doesn't my *= operator work?
+
Why doesn't my *= operator + work?
Does Boost.Python work with Mac OS X?
+ +
How can I find the existing PyObject that holds a + C++ object?
+
-

Is return_internal reference efficient?

+

Is return_internal_reference efficient?

Q: I have an object composed of 12 doubles. A const& to @@ -70,6 +75,7 @@ cycles.

+

How can I wrap functions which take C++ containers as arguments?

@@ -161,7 +167,7 @@ cvs -d:pserver:anonymous@cvs.cctbx.sourceforge.net:/cvsroot/cctbx login cvs -d:pserver:anonymous@cvs.cctbx.sourceforge.net:/cvsroot/cctbx co scitbx - +

fatal error C1204:Compiler limit:internal structure overflow

@@ -203,9 +209,9 @@ void more_of_my_module() can always pass a reference to the class_ object to a function in another source file, and call some of its member functions (e.g. .def(...)) in the auxilliary source - file: + file: -

more_of_my_class.cpp: +

more_of_my_class.cpp:

 void more_of_my_class(class<my_class>& x)
 {
@@ -221,28 +227,25 @@ void more_of_my_class(class<my_class>& x)
       
     
 
+

How do I debug my Python extensions?

-

Greg Burley gives the following answer for Unix GCC users: +

Greg Burley gives the following answer for Unix GCC users:

-Once you have created a boost python extension for your c++ library or -class, you may need to debug the code. Afterall this is one of the -reasons for wrapping the library in python. An expected side-effect or -benefit of using BPL is that debugging should be isolated to the c++ -library that is under test, given that python code is minimal and -boost::python either works or it doesn't. (ie. While errors can occur -when the wrapping method is invalid, most errors are caught by the -compiler ;-). - -

- -The basic steps required to initiate a gdb session to debug a c++ -library via python are shown here. Note, however that you should start -the gdb session in the directory that contains your BPL my_ext.so -module. - + Once you have created a boost python extension for your c++ library or + class, you may need to debug the code. Afterall this is one of the + reasons for wrapping the library in python. An expected side-effect or + benefit of using BPL is that debugging should be isolated to the c++ + library that is under test, given that python code is minimal and + boost::python either works or it doesn't. (ie. While errors can occur + when the wrapping method is invalid, most errors are caught by the + compiler ;-). +

The basic steps required to initiate a gdb session to debug a c++ + library via python are shown here. Note, however that you should start + the gdb session in the directory that contains your BPL my_ext.so + module.

 (gdb) target exec python
 (gdb) run
@@ -258,63 +261,54 @@ Current language:  auto; currently c++
 
-

+

Greg's approach works even better using Emacs' "gdb" + command, since it will show you each line of source as you step through + it.

-Greg's approach works even better using Emacs' -"gdb" command, since it will show you each line -of source as you step through it. +

On Windows, my favorite debugging solution is the debugger that + comes with Microsoft Visual C++ 7. This debugger seems to work with code + generated by all versions of Microsoft and Metrowerks toolsets; it's rock + solid and "just works" without requiring any special tricks from the + user.

-

- -On Windows, my favorite debugging solution is the debugger that comes -with Microsoft Visual C++ 7. This debugger seems to work with code -generated by all versions of Microsoft and Metrowerks toolsets; it's -rock solid and "just works" without requiring any special -tricks from the user. - -

- -Unfortunately for Cygwin and MinGW users, as of this writing gdb on -Windows has a very hard time dealing with shared libraries, which -could make Greg's approach next to useless for you. My best advice for -you is to use Metrowerks C++ for compiler conformance and Microsoft -Visual Studio as a debugger when you need one. - -

Debugging extensions through Boost.Build

- -If you are launching your extension module tests with Boost.Build using the -boost-python-runtest rule, you can ask it to launch your -debugger for you by adding "-sPYTHON_LAUNCH=debugger" -to your bjam command-line: +

Unfortunately for Cygwin and MinGW users, as of this writing gdb on + Windows has a very hard time dealing with shared libraries, which could + make Greg's approach next to useless for you. My best advice for you is + to use Metrowerks C++ for compiler conformance and Microsoft Visual + Studio as a debugger when you need one.

+

Debugging extensions through Boost.Build

+ If you are launching your extension module tests with Boost.Build using the + boost-python-runtest rule, you can ask it to launch your + debugger for you by adding "-sPYTHON_LAUNCH=debugger" to your bjam + command-line:
-bjam -sTOOLS=metrowerks "-sPYTHON_LAUNCH=devenv /debugexe" test
+bjam -sTOOLS=metrowerks "-sPYTHON_LAUNCH=devenv /debugexe" test
 bjam -sTOOLS=gcc -sPYTHON_LAUNCH=gdb test
 
+ It can also be extremely useful to add the -d+2 option when + you run your test, because Boost.Build will then show you the exact + commands it uses to invoke it. This will invariably involve setting up + PYTHONPATH and other important environment variables such as + LD_LIBRARY_PATH which may be needed by your debugger in order to get + things to work right. -It can also be extremely useful to add the -d+2 option -when you run your test, because Boost.Build will then show you the -exact commands it uses to invoke it. This will invariably involve -setting up PYTHONPATH and other important environment variables such -as LD_LIBRARY_PATH which may be needed by your debugger in order to -get things to work right. - +

Why doesn't my *= operator work?

-
-Q: I have exported my class to python, with many overloaded operators. it -works fine for me except the *= operator. It always tells -me "can't multiply sequence with non int type". If I use -p1.__imul__(p2) instead of p1 *= -p2, it successfully executes my code. What's wrong with -me? - -

A: There's nothing wrong with you. This is a bug in Python -2.2. You can see the same effect in Pure Python (you can learn a lot -about what's happening in Boost.Python by playing with new-style -classes in Pure Python). +

+ Q: I have exported my class to python, with many overloaded + operators. it works fine for me except the *= + operator. It always tells me "can't multiply sequence with non int + type". If I use p1.__imul__(p2) instead of + p1 *= p2, it successfully executes my code. What's + wrong with me? +

A: There's nothing wrong with you. This is a bug in Python + 2.2. You can see the same effect in Pure Python (you can learn a lot + about what's happening in Boost.Python by playing with new-style + classes in Pure Python).

 >>> class X(object):
 ...     def __imul__(self, x):
@@ -323,44 +317,103 @@ classes in Pure Python).
 >>> x = X()
 >>> x *= 1
 
+ To cure this problem, all you need to do is upgrade your Python to + version 2.2.1 or later. +
-To cure this problem, all you need to do is upgrade your Python to -version 2.2.1 or later. - -
- +

Does Boost.Python work with Mac OS X?

-
-

The short answer: as of January 2003, unfortunately not. -

-The longer answer: using Mac OS 10.2.3 with the December Developer's Kit, -Python 2.3a1, and bjam's darwin-tools.jam, Boost.Python compiles fine, -including the examples. However, there are problems at runtime -(see http://mail.python.org/pipermail/c++-sig/2003-January/003267.html). -Solutions are currently unknown. -

-It is known that under certain circumstances objects are double-destructed. -See http://mail.python.org/pipermail/c++-sig/2003-January/003278.html" -for details. It is not clear however if this problem is related to -the Boost.Python runtime issues. -

+
+

The short answer: as of January 2003, unfortunately not.

+

The longer answer: using Mac OS 10.2.3 with the December Developer's + Kit, Python 2.3a1, and bjam's darwin-tools.jam, Boost.Python compiles + fine, including the examples. However, there are problems at runtime + (see http://mail.python.org/pipermail/c++-sig/2003-January/003267.html). + Solutions are currently unknown.

+ +

It is known that under certain circumstances objects are + double-destructed. See http://mail.python.org/pipermail/c++-sig/2003-January/003278.html" + for details. It is not clear however if this problem is related to the + Boost.Python runtime issues.

+
+ +
+

How can I find the existing PyObject that holds a C++ + object?

+ +
+ "I am wrapping a function that always returns a pointer to an + already-held C++ object." +
+ One way to do that is to hijack the mechanisms used for wrapping a class + with virtual functions. If you make a wrapper class with an initial + PyObject* constructor argument and store that PyObject* as "self", you + can get back to it by casting down to that wrapper type in a thin wrapper + function. For example: +
+class X { X(int); virtual ~X(); ... };
+X* f();  // known to return Xs that are managed by Python objects
+
+
+// wrapping code
+
+struct X_wrap : X
+{
+    X_wrap(PyObject* self, int v) : self(self), X(v) {}
+    PyObject* self;
+};
+
+handle<> f_wrap()
+{
+    X_wrap* xw = dynamic_cast<X_wrap*>(f());
+    assert(xw != 0);
+    return handle<>(borrowed(xw->self));
+}
+
+...
+
+def("f", f_wrap());
+class_<X,X_wrap>("X", init<int>())
+   ...
+   ;
+
+ Of course, if X has no virtual functions you'll have to use + static_cast instead of dynamic_cast with no + runtime check that it's valid. This approach also only works if the + X object was constructed from Python, because + Xs constructed from C++ are of course never + X_wrap objects. + +

Another approach to this requires some work on Boost.Python, but it's + work we've been meaning to get to anyway. Currently, when a + shared_ptr<X> is converted from Python, the shared_ptr + actually manages a reference to the containing Python object. I plan to + make it so that when a shared_ptr<X> is converted back to Python, + the library checks to see if it's one of those "Python object managers" + and if so just returns the original Python object. To exploit this you'd + have to be able to change the C++ code you're wrapping so that it deals + with shared_ptr instead of raw pointers.

+ +

There are other approaches too. The functions that receive the Python + object that you eventually want to return could be wrapped with a thin + wrapper that records the correspondence between the object address and + its containing Python object, and you could have your f_wrap function + look in that mapping to get the Python object out.


Revised - 14 January, 2003 + 23 January, 2003

© Copyright Dave Abrahams 2002-2003. All Rights - Reserved.

+ "../../../../people/dave_abrahams.htm">Dave Abrahams 2002-2003. All + Rights Reserved.