From foo.Clark at gmail.com Fri Jul 1 04:08:29 2005 From: foo.Clark at gmail.com (Clark) Date: Fri, 1 Jul 2005 10:08:29 +0800 Subject: [C++-sig] How to deal with array? Message-ID: <20050701020828.GA14499@BigDell> Hi, Can I expose a C++ array to python with Boost.Python? And Can I use a python list conveniently in C++? For example, there is a C++ class as follows class A { private: int c[4]; public: int d[10]; void set(int *n) { for(int i = 0; i < 4; ++i) c[i] = n[i] } } and I want use class A above in Python like this a = A() print a.d[2] n = [1, 2, ,3, 4] a.set(n) Can you give me some hints? From rwgk at yahoo.com Fri Jul 1 09:01:32 2005 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Fri, 1 Jul 2005 00:01:32 -0700 (PDT) Subject: [C++-sig] How to deal with array? In-Reply-To: <20050701020828.GA14499@BigDell> Message-ID: <20050701070132.44458.qmail@web31509.mail.mud.yahoo.com> There are a number of possible solutions. One that I explored recently and is particularly non-intrusive goes like this: 1. Copy this file to your space (remove the #include if it is still version 1.1.1.1) and change the namespaces to your liking: http://cvs.sourceforge.net/viewcvs.py/cctbx/gltbx/pointer_args_bpl.h?view=markup 2. Implement a thin wrapper like this (untested): void A_set(A& self, boost::python::object const& py_n) { boost_python::converter n_proxy("n", py_n, 4, false); int* n = n_proxy.get(); A.set(n); } 3. Wrap like this (also untested): class_("A") .def("set", A_set) ; HTH, Ralf --- Clark wrote: > Hi, > Can I expose a C++ array to python with Boost.Python? And Can I use a > python list conveniently in C++? > > For example, there is a C++ class as follows > class A > { > private: > int c[4]; > public: > int d[10]; > > void set(int *n) > { > for(int i = 0; i < 4; ++i) > c[i] = n[i] > } > } > and I want use class A above in Python like this > a = A() > print a.d[2] > n = [1, 2, ,3, 4] > a.set(n) > > Can you give me some hints? __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From markus.schoepflin at comsoft.de Fri Jul 1 16:41:23 2005 From: markus.schoepflin at comsoft.de (=?ISO-8859-1?Q?Markus_Sch=F6pflin?=) Date: Fri, 01 Jul 2005 16:41:23 +0200 Subject: [C++-sig] [boost.python] Interoperability with boost.bind Message-ID: Is boost.python compatible with boost.bind (see example below)? If yes, what am I doing wrong? The compiler used is g++ 3.2.3, boost version is 1.32. Example: int foo(int bar) { return bar; } ... def("foo", foo); // compiles ok def("foo", boost::bind(foo, _1)); // gives error The error message boils down to: boost/python/make_function.hpp:103: error: no matching function for call to `get_signature(boost::_bi::bind_t > >&)' TIA, Markus From petrucio at hoplon.com Fri Jul 1 17:40:09 2005 From: petrucio at hoplon.com (Petrucio) Date: Fri, 01 Jul 2005 12:40:09 -0300 Subject: [C++-sig] How to deal with array? In-Reply-To: <20050701020828.GA14499@BigDell> References: <20050701020828.GA14499@BigDell> Message-ID: <6.0.2.0.1.20050701123336.01d32a20@mail.hoplon.com> Just like the similar quation about argument pointers returning values, to solve this kind of problem I found SWIG to be easier, using pre-made typemaps under carrays.i: http://www.swig.org/Doc1.3/Library.html#Library_nn5 PS: Sorry about bringing SWIG all the time in a Boost.Pyhon list. I just think it's best suited for a lower-level, basic typed heavy API. At 23:08 30/6/2005, you wrote: >Hi, >Can I expose a C++ array to python with Boost.Python? And Can I use a >python list conveniently in C++? > >For example, there is a C++ class as follows > class A > { > private: > int c[4]; > public: > int d[10]; > > void set(int *n) > { > for(int i = 0; i < 4; ++i) > c[i] = n[i] > } > } >and I want use class A above in Python like this > a = A() > print a.d[2] > n = [1, 2, ,3, 4] > a.set(n) > >Can you give me some hints? >_______________________________________________ >C++-sig mailing list >C++-sig at python.org >http://mail.python.org/mailman/listinfo/c++-sig From paul at pecm.nl Fri Jul 1 20:00:07 2005 From: paul at pecm.nl (Paul Melis) Date: Fri, 01 Jul 2005 20:00:07 +0200 Subject: [C++-sig] Wrapping std::vector Message-ID: <42C584A7.3030607@pecm.nl> Hello, I have an abstract class and a std::vector<> of pointers to this class. A routine in my c++ code fills a vector with objects of classes derived from the abstract class. I'd like to iterate over the vector in python and use each of the items in the vector depending on the type of derived class. I have the following: #include #include #include using namespace boost::python; class Abstract { public: virtual void f() =0; }; class Concrete1 : public Abstract { public: virtual void f() { } }; typedef std::vector ListOfObjects; class DoesSomething { public: DoesSomething() {} ListOfObjects returnList() { ListOfObjects lst; lst.push_back(new Concrete1()); return lst; } }; BOOST_PYTHON_MODULE(test) { class_("Abstract", no_init) ; class_("ListOfObjects") .def( vector_indexing_suite() ) ; class_("DoesSomething") .def("returnList", &DoesSomething::returnList) ; } Now, when I put this stuff in a python module and try to use it I get: Python 2.4 (#60, Nov 30 2004, 11:49:19) [MSC v.1310 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import test >>> dir(test) ['Abstract', 'DoesSomething', 'ListOfObjects', '__doc__', '__file__', '__name__'] >>> d = test.DoesSomething() >>> d.returnList() >>> lst = d.returnList() >>> lst[0] Traceback (most recent call last): File "", line 1, in ? TypeError: No to_python (by-value) converter found for C++ type: class Abstract >>> I suspect that boost.python will wrap the return value of returnList() as a pointer to Abstract, without the possibility at runtime to look at the actual object type. Is this something I would have to code by hand? For example, by making a routine that takes a pointer to Abstract and uses dynamic_cast<> to test which of the concrete classes the object actually is from? Paul From dirgesh.patel at hp.com Sat Jul 2 00:07:50 2005 From: dirgesh.patel at hp.com (Dirgesh Patel) Date: Fri, 1 Jul 2005 15:07:50 -0700 Subject: [C++-sig] using libtool in boost.python Message-ID: how can i use libtool in boost.python with Jamfile From rwgk at yahoo.com Sat Jul 2 01:20:42 2005 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Fri, 1 Jul 2005 16:20:42 -0700 (PDT) Subject: [C++-sig] [boost.python] Interoperability with boost.bind In-Reply-To: Message-ID: <20050701232042.88012.qmail@web31504.mail.mud.yahoo.com> I don't know where David is... Until he replies a potentially silly suggestion (since I don't understand boost::bind very much): is it besides the point to make a thin wrapper int bound_foo(int bar) { boost::bind(foo, _1)(bar); } and to .def("foo", bound_foo); ? --- Markus Sch?pflin wrote: > Is boost.python compatible with boost.bind (see example below)? If yes, > what am I doing wrong? The compiler used is g++ 3.2.3, boost version is 1.32. > > Example: > > int foo(int bar) { return bar; } > ... > def("foo", foo); // compiles ok > def("foo", boost::bind(foo, _1)); // gives error > > The error message boils down to: > > boost/python/make_function.hpp:103: error: no matching function for call to > `get_signature(boost::_bi::bind_t boost::_bi::list1 > >&)' > > TIA, Markus ____________________________________________________ Yahoo! Sports Rekindle the Rivalries. Sign up for Fantasy Football http://football.fantasysports.yahoo.com From dave at boost-consulting.com Sat Jul 2 02:07:51 2005 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 01 Jul 2005 20:07:51 -0400 Subject: [C++-sig] [boost.python] Interoperability with boost.bind References: Message-ID: Markus Sch?pflin writes: > Is boost.python compatible with boost.bind (see example below)? Not in that way, no. The requirements of def() are clearly spelled out in http://www.boost.org/libs/python/doc/v2/def.html#def-spec, and bind_t<> specializations do not meet them ... mostly because I don't have a way to deduce the signature of a bind expression. However, you can do: def( "foo" , make_function( bind(foo,_1) , default_call_policies() , boost::mpl::vector() ) ) See http://www.boost.org/libs/python/doc/v2/make_function.html -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Sat Jul 2 02:09:14 2005 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 01 Jul 2005 20:09:14 -0400 Subject: [C++-sig] [boost.python] Interoperability with boost.bind References: <20050701232042.88012.qmail@web31504.mail.mud.yahoo.com> Message-ID: "Ralf W. Grosse-Kunstleve" writes: > I don't know where David is... Somerville, as usual? -- Dave Abrahams Boost Consulting www.boost-consulting.com From foo.Clark at gmail.com Sat Jul 2 19:39:28 2005 From: foo.Clark at gmail.com (Clark) Date: Sun, 3 Jul 2005 01:39:28 +0800 Subject: [C++-sig] How to deal with array? In-Reply-To: <20050701070132.44458.qmail@web31509.mail.mud.yahoo.com> References: <20050701020828.GA14499@BigDell> <20050701070132.44458.qmail@web31509.mail.mud.yahoo.com> Message-ID: <20050702173928.GA21740@BigDell> Thanks. I'll try it. And can you give me somthing about other solutions? On Fri, Jul 01, 2005 at 12:01:32AM -0700, Ralf W. Grosse-Kunstleve wrote: > There are a number of possible solutions. One that I explored recently and is > particularly non-intrusive goes like this: > > 1. Copy this file to your space (remove the #include if it is still > version 1.1.1.1) and change the namespaces to your liking: > > > http://cvs.sourceforge.net/viewcvs.py/cctbx/gltbx/pointer_args_bpl.h?view=markup > > 2. Implement a thin wrapper like this (untested): > > void > A_set(A& self, boost::python::object const& py_n) > { > boost_python::converter n_proxy("n", py_n, 4, false); > int* n = n_proxy.get(); > A.set(n); > } > > 3. Wrap like this (also untested): > > class_("A") > .def("set", A_set) > ; > > HTH, > Ralf > > --- Clark wrote: > > > Hi, > > Can I expose a C++ array to python with Boost.Python? And Can I use a > > python list conveniently in C++? > > > > For example, there is a C++ class as follows > > class A > > { > > private: > > int c[4]; > > public: > > int d[10]; > > > > void set(int *n) > > { > > for(int i = 0; i < 4; ++i) > > c[i] = n[i] > > } > > } > > and I want use class A above in Python like this > > a = A() > > print a.d[2] > > n = [1, 2, ,3, 4] > > a.set(n) > > > > Can you give me some hints? > > > __________________________________________________ > Do You Yahoo!? > Tired of spam? Yahoo! Mail has the best spam protection around > http://mail.yahoo.com > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig From dave at boost-consulting.com Sun Jul 3 03:53:10 2005 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 02 Jul 2005 21:53:10 -0400 Subject: [C++-sig] In a C++ extension, how to use a C++ class exported in another extension References: <20050630150541.GA12758@BigDell> <20050630211702.2749.qmail@web31505.mail.mud.yahoo.com> Message-ID: "Ralf W. Grosse-Kunstleve" writes: > Thanks for posting this. It is very interesting! > > David, how difficult would it be to provide something like > > boost::python::arg_from_swig_object(); > > so that we could wrap functions taking SWIG-wrapped arguments > directly? I don't know enough about what SWIG does to say for sure, but I presume it is generating a type object for each class you wrap... (**) > I guess there is no easy way to construct SWIG-wrapped return values without a > lot of support from SWIG, Perhaps not; I don't know what SWIG provides. > but automatically extracting the pointer to turn it > into a T*, T&, const T*, const T& argument seems like something that may not be > too hard... true? > > Looking some more, isn't this almost it? > > http://www.boost.org/libs/python/doc/v2/lvalue_from_pytype.html Yes. > But we want to do it without having the equivalent of > noddy_NoddyType, (**) ...just like noddy_NoddyType. Are you sure we don't want to have the equivalent of that? > just knowing that ((PySwigObject*)obj.ptr())->ptr gives us the T*. Oh, I see; all Swig objects have the same type? Well you need some way to identify the Python objects for which the above statement is true, unless you want to forego all error checking and just allow a crash if a Swig-wrapped Foo is passed where a Swig-wrapped Bar is expected. -- Dave Abrahams Boost Consulting www.boost-consulting.com From rwgk at yahoo.com Sun Jul 3 16:20:18 2005 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Sun, 3 Jul 2005 07:20:18 -0700 (PDT) Subject: [C++-sig] How to deal with array? In-Reply-To: <20050702173928.GA21740@BigDell> Message-ID: <20050703142018.41016.qmail@web31514.mail.mud.yahoo.com> --- Clark wrote: > Thanks. I'll try it. And can you give me somthing about other solutions? Can you change the wrapped classes? If yes, you could use boost::array instead of the plain C int [4]. The signature of your method would become set(boost::array const&) instead of set(int*). Then you could use this file (no dependencies other than Boost): http://cvs.sourceforge.net/viewcvs.py/cctbx/scitbx/include/scitbx/boost_python/container_conversions.h?view=markup to define automatic list or tuple -> boost::array conversions. I.e. you could wrap your set method directly. See also: http://www.boost.org/libs/python/doc/v2/faq.html#question2 I've mentioned this many times before on this list. Google for container_conversions to find the messages. This doesn't support write_back, though (the previous suggestion does). You could use both what I suggested before and what I am suggesting here at the same time, I believe. There is also the vector indexing suite which comes with Boost.Python (see docs), but this is more for large arrays. Cheers, Ralf __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From rwgk at yahoo.com Sun Jul 3 20:56:12 2005 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Sun, 3 Jul 2005 11:56:12 -0700 (PDT) Subject: [C++-sig] In a C++ extension, how to use a C++ class exported in another extension In-Reply-To: Message-ID: <20050703185612.96550.qmail@web31508.mail.mud.yahoo.com> --- David Abrahams wrote: > > Looking some more, isn't this almost it? > > > > http://www.boost.org/libs/python/doc/v2/lvalue_from_pytype.html > > Yes. Cool! > > just knowing that ((PySwigObject*)obj.ptr())->ptr gives us the T*. > > Oh, I see; all Swig objects have the same type? Yes! > Well you need some way to identify the Python objects for which the > above statement is true, unless you want to forego all error checking > and just allow a crash if a Swig-wrapped Foo is passed where a > Swig-wrapped Bar is expected. I hadn't though of that. Thanks, David! Encouraged by your "Yes" above I gave it a good push. Here is the result: http://cvs.sourceforge.net/viewcvs.py/cctbx/boost_adaptbx/swig_args_ext.cpp?view=markup (Also attached.) This solution is based on what I found in SWIG-1.3.24/Lib/python/pyrun.swg. At the heart of the solution is this simple fragment: static void* extract(PyObject* op) \ { \ if (std::strcmp(op->ob_type->tp_name, "PySwigObject") != 0) return 0; \ PySwigObject* swig_obj_ptr = reinterpret_cast(op); \ if (std::strcmp(swig_obj_ptr->desc, "_p_" # T) != 0) return 0; \ return swig_obj_ptr->ptr; \ } \ And here is the corresponding test script: http://cvs.sourceforge.net/viewcvs.py/cctbx/boost_adaptbx/tst_swig_args.py?view=markup The test script slightly edited: import example # SWIG-1.3.24/Examples/python/class import boost_python_swig_args_ext c = example.Circle(10) c.x = 20 c.y = 30 s = example.Square(10) s.x = -10 s.y = 5 boost_python_swig_args_ext.show(c.this) boost_python_swig_args_ext.show(s.this) The test runs successfully under Linux. It proves that the overloaded show() function works correctly, which means the simple strcmp() logic in the C++ fragment above works as it should. I also used valgrind and did a leak check. If someone wants to reproduce: gunzip -c swig-1.3.24.tar.gz | tar xf - cd SWIG-1.3.24 ./configure make cd Examples/python/class make cp _example.so example.py ar r libswig_class_example.a example.o Then compile and link boost_python_swig_args_ext with -lswig_class_example. David, would you want to include the core of swig_args_ext.cpp in, e.g., boost/python/swig_arg.h? I think it would be a valuable addition. There are many SWIG-wrapped libraries. People could easily use them while writing their own extensions with Boost.Python. Cheers, Ralf __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: swig_args_ext.cpp URL: From dave at boost-consulting.com Mon Jul 4 01:31:19 2005 From: dave at boost-consulting.com (David Abrahams) Date: Sun, 03 Jul 2005 19:31:19 -0400 Subject: [C++-sig] In a C++ extension, how to use a C++ class exported in another extension References: <20050703185612.96550.qmail@web31508.mail.mud.yahoo.com> Message-ID: "Ralf W. Grosse-Kunstleve" writes: > --- David Abrahams wrote: >> > Looking some more, isn't this almost it? >> > >> > http://www.boost.org/libs/python/doc/v2/lvalue_from_pytype.html >> >> Yes. > > Cool! > >> > just knowing that ((PySwigObject*)obj.ptr())->ptr gives us the T*. >> >> Oh, I see; all Swig objects have the same type? > > Yes! > >> Well you need some way to identify the Python objects for which the >> above statement is true, unless you want to forego all error checking >> and just allow a crash if a Swig-wrapped Foo is passed where a >> Swig-wrapped Bar is expected. > > I hadn't though of that. Thanks, David! > > Encouraged by your "Yes" above I gave it a good push. Here is the > result: > > > http://cvs.sourceforge.net/viewcvs.py/cctbx/boost_adaptbx/swig_args_ext.cpp?view=markup > > (Also attached.) > > This solution is based on what I found in SWIG-1.3.24/Lib/python/pyrun.swg. > At the heart of the solution is this simple fragment: > > static void* extract(PyObject* op) \ > { \ > if (std::strcmp(op->ob_type->tp_name, "PySwigObject") != 0) > return 0; \ Isn't there a type object somewhere you can compare ob_type with? > PySwigObject* swig_obj_ptr = reinterpret_cast(op); \ This should be static_cast. > if (std::strcmp(swig_obj_ptr->desc, "_p_" # T) != 0) return 0; \ Heh, so that's how they do it. Pretty lame, IMO. Well, inheritance won't work; a swig-wrapped Derived won't be able to be passed where a Base is expected. If that doesn't matter, it's fine. > return swig_obj_ptr->ptr; \ > } \ > > And here is the corresponding test script: > > > http://cvs.sourceforge.net/viewcvs.py/cctbx/boost_adaptbx/tst_swig_args.py?view=markup > > The test script slightly edited: > > import example # SWIG-1.3.24/Examples/python/class > import boost_python_swig_args_ext > > c = example.Circle(10) > c.x = 20 > c.y = 30 > > s = example.Square(10) > s.x = -10 > s.y = 5 > > boost_python_swig_args_ext.show(c.this) > boost_python_swig_args_ext.show(s.this) You should have part of the test that shows non-matching types are rejected. > The test runs successfully under Linux. It proves that the overloaded > show() function works correctly, which means the simple strcmp() logic > in the C++ fragment above works as it should. I also used valgrind and > did a leak check. If someone wants to reproduce: > > gunzip -c swig-1.3.24.tar.gz | tar xf - > cd SWIG-1.3.24 > ./configure > make > cd Examples/python/class > make > cp _example.so example.py > ar r libswig_class_example.a example.o > > Then compile and link boost_python_swig_args_ext with > -lswig_class_example. > > David, would you want to include the core of swig_args_ext.cpp in, > e.g., boost/python/swig_arg.h? I think it would be a valuable > addition. There are many SWIG-wrapped libraries. People could easily > use them while writing their own extensions with Boost.Python. Sounds great! Needs docs, of course ;-) -- Dave Abrahams Boost Consulting www.boost-consulting.com From foo.Clark at gmail.com Mon Jul 4 05:46:11 2005 From: foo.Clark at gmail.com (Clark) Date: Mon, 4 Jul 2005 11:46:11 +0800 Subject: [C++-sig] In a C++ extension, how to use a C++ class exported in another extension In-Reply-To: <20050630211702.2749.qmail@web31505.mail.mud.yahoo.com> References: <20050630150541.GA12758@BigDell> <20050630211702.2749.qmail@web31505.mail.mud.yahoo.com> Message-ID: <20050704034611.GA31236@BigDell> On Thu, Jun 30, 2005 at 02:17:02PM -0700, Ralf W. Grosse-Kunstleve wrote: > Thanks for posting this. It is very interesting! > > David, how difficult would it be to provide something like > > boost::python::arg_from_swig_object(); > > so that we could wrap functions taking SWIG-wrapped arguments directly? > I guess there is no easy way to construct SWIG-wrapped return values without a > lot of support from SWIG, but automatically extracting the pointer to turn it Yes. But we can still emulate what SWIG does to make a C++ Object be a Python Object, and then return it. > into a T*, T&, const T*, const T& argument seems like something that may not be > too hard... true? > > Looking some more, isn't this almost it? > > http://www.boost.org/libs/python/doc/v2/lvalue_from_pytype.html > > But we want to do it without having the equivalent of noddy_NoddyType, just > knowing that ((PySwigObject*)obj.ptr())->ptr gives us the T*. > > Cheers, > Ralf > > --- Clark wrote: > > > It takes much time of me to solve this problem. > > > > The answer is: > > A class member named "this" is added to every python class wrapped by > > SWIG. The "this" is a "PySwigObject", which has a member points to > > the C++ 'this' pointer. > > > > __________________________________ > Do you Yahoo!? > Read only the mail you want - Yahoo! Mail SpamGuard. > http://promotions.yahoo.com/new_mail > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig From foo.Clark at gmail.com Mon Jul 4 06:07:36 2005 From: foo.Clark at gmail.com (Clark) Date: Mon, 4 Jul 2005 12:07:36 +0800 Subject: [C++-sig] In a C++ extension, how to use a C++ class exported in another extension In-Reply-To: References: <20050630150541.GA12758@BigDell> <20050630211702.2749.qmail@web31505.mail.mud.yahoo.com> Message-ID: <20050704040736.GB31236@BigDell> On Sat, Jul 02, 2005 at 09:53:10PM -0400, David Abrahams wrote: > "Ralf W. Grosse-Kunstleve" writes: > > > Thanks for posting this. It is very interesting! > > > > David, how difficult would it be to provide something like > > > > boost::python::arg_from_swig_object(); > > > > so that we could wrap functions taking SWIG-wrapped arguments > > directly? > > I don't know enough about what SWIG does to say for sure, but I > presume it is generating a type object for each class you wrap... (**) > > > I guess there is no easy way to construct SWIG-wrapped return values without a > > lot of support from SWIG, > > Perhaps not; I don't know what SWIG provides. > > > but automatically extracting the pointer to turn it > > into a T*, T&, const T*, const T& argument seems like something that may not be > > too hard... true? > > > > Looking some more, isn't this almost it? > > > > http://www.boost.org/libs/python/doc/v2/lvalue_from_pytype.html > > Yes. > > > But we want to do it without having the equivalent of > > noddy_NoddyType, > > (**) ...just like noddy_NoddyType. Are you sure we don't want to have > the equivalent of that? > > > just knowing that ((PySwigObject*)obj.ptr())->ptr gives us the T*. > > Oh, I see; all Swig objects have the same type? Yes, they are all PySwigObject. > > Well you need some way to identify the Python objects for which the > above statement is true, unless you want to forego all error checking > and just allow a crash if a Swig-wrapped Foo is passed where a > Swig-wrapped Bar is expected. Sometimes it's critical. For example, to paint on screen efficiently, we must use the DC's methods in C++ directly. But because usually the GUI or framework is written in Python, we can only get the DC as a Python Object. Maybe we can also emulate the behaviors of SWIG to do error checking and it may not be very easy. It may not be implemented in Boost.Python soon. And I can't wait any more for my project has began. > > -- > Dave Abrahams > Boost Consulting > www.boost-consulting.com > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig From markus.schoepflin at comsoft.de Mon Jul 4 13:17:19 2005 From: markus.schoepflin at comsoft.de (=?ISO-8859-1?Q?Markus_Sch=F6pflin?=) Date: Mon, 04 Jul 2005 13:17:19 +0200 Subject: [C++-sig] [boost.python] Interoperability with boost.bind In-Reply-To: <20050701232042.88012.qmail@web31504.mail.mud.yahoo.com> References: <20050701232042.88012.qmail@web31504.mail.mud.yahoo.com> Message-ID: Ralf W. Grosse-Kunstleve wrote: > I don't know where David is... > Until he replies a potentially silly suggestion (since I don't understand > boost::bind very much): is it besides the point to make a thin wrapper > > int > bound_foo(int bar) > { > boost::bind(foo, _1)(bar); > } > > and to > > .def("foo", bound_foo); > > ? Thanks for the suggestion, but the use of bind was meant to avoid the need for a wrapper function. Markus From markus.schoepflin at comsoft.de Mon Jul 4 13:21:37 2005 From: markus.schoepflin at comsoft.de (=?ISO-8859-1?Q?Markus_Sch=F6pflin?=) Date: Mon, 04 Jul 2005 13:21:37 +0200 Subject: [C++-sig] [boost.python] Interoperability with boost.bind In-Reply-To: References: Message-ID: David Abrahams wrote: > Markus Sch?pflin writes: >>Is boost.python compatible with boost.bind (see example below)? > Not in that way, no. The requirements of def() are clearly spelled > out in http://www.boost.org/libs/python/doc/v2/def.html#def-spec, and > bind_t<> specializations do not meet them ... mostly because I don't > have a way to deduce the signature of a bind expression. > > However, you can do: > > def( > "foo" > , make_function( > bind(foo,_1) > , default_call_policies() > , boost::mpl::vector() > ) > ) > > See http://www.boost.org/libs/python/doc/v2/make_function.html Thanks for the answer, Dave. IOW, if there would be a way to get the signature of the bind expression, maybe via some support from bind itself, there would be a way to make to original example work, right? Markus From dave at boost-consulting.com Mon Jul 4 14:22:12 2005 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 04 Jul 2005 08:22:12 -0400 Subject: [C++-sig] In a C++ extension, how to use a C++ class exported in another extension References: <20050630150541.GA12758@BigDell> <20050630211702.2749.qmail@web31505.mail.mud.yahoo.com> <20050704040736.GB31236@BigDell> Message-ID: Clark writes: >> >> Oh, I see; all Swig objects have the same type? > Yes, they are all PySwigObject. Please try to leave a blank line above and below quoted material; otherwise it's hard to pick out what you're saying. >> Well you need some way to identify the Python objects for which the >> above statement is true, unless you want to forego all error checking >> and just allow a crash if a Swig-wrapped Foo is passed where a >> Swig-wrapped Bar is expected. > Sometimes it's critical. Sometimes it's critical to... identify the Python objects for which the above statement is true? Forego all error checking and allow a crash? Something else? > For example, to paint on screen efficiently, we must use the DC's > methods in C++ directly. But because usually the GUI or framework is > written in Python, we can only get the DC as a Python Object. I don't see the connection between that scenario and anything we're discussing. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Mon Jul 4 14:24:00 2005 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 04 Jul 2005 08:24:00 -0400 Subject: [C++-sig] [boost.python] Interoperability with boost.bind References: Message-ID: Markus Sch?pflin writes: > David Abrahams wrote: > >> Markus Sch?pflin writes: > >>>Is boost.python compatible with boost.bind (see example below)? > >> Not in that way, no. The requirements of def() are clearly spelled >> out in http://www.boost.org/libs/python/doc/v2/def.html#def-spec, and >> bind_t<> specializations do not meet them ... mostly because I don't >> have a way to deduce the signature of a bind expression. >> >> However, you can do: >> >> def( >> "foo" >> , make_function( >> bind(foo,_1) >> , default_call_policies() >> , boost::mpl::vector() >> ) >> ) >> >> See http://www.boost.org/libs/python/doc/v2/make_function.html > > Thanks for the answer, Dave. IOW, if there would be a way to get the > signature of the bind expression, There is none. Consider that you can wrap function objects with templated operator(): struct F { template T* operator()(T) const; }; what is the signature of bind(F(),_1) ? > maybe via some support from bind itself, there would be a way to > make to original example work, right? Right. But there is no way to do it. -- Dave Abrahams Boost Consulting www.boost-consulting.com From markus.schoepflin at comsoft.de Mon Jul 4 16:07:27 2005 From: markus.schoepflin at comsoft.de (=?ISO-8859-1?Q?Markus_Sch=F6pflin?=) Date: Mon, 04 Jul 2005 16:07:27 +0200 Subject: [C++-sig] [boost.python] char arrays in structs Message-ID: Using gcc-3.4.3 and boost.python 1.32.0. Full example: ---%<--- #include #include typedef char bar_t[4]; struct foo { bar_t bar; foo() { bar[0] = 'b'; bar[1] = 'a'; bar[2] = 'r'; bar[3] = 0; } }; BOOST_PYTHON_MODULE(test) { using namespace boost::python; class_("foo") .def_readonly("bar", &foo::bar) ; } --->%--- The compiles and links ok, but when using it from python I get the following error: Python 2.3 (#1, Jul 30 2003, 14:14:00) [GCC 3.3 20030226 (prerelease) (SuSE Linux)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> from test import * >>> print foo().bar Traceback (most recent call last): File "", line 1, in ? TypeError: No to_python (by-value) converter found for C++ type: char [4] So I went ahead and added a custom converter for bar_t like so: struct bar_t_to_python_str { static PyObject* convert(bar_t const &s) { return boost::python::incref(boost::python::object(s).ptr()); } }; and in BOOST_PYTHON_MODULE(test): to_python_converter(); Is it to be expected that I do need a custom type converter for this? Or do I miss something? TIA, Markus From rwgk at yahoo.com Mon Jul 4 17:26:11 2005 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Mon, 4 Jul 2005 08:26:11 -0700 (PDT) Subject: [C++-sig] [boost.python] char arrays in structs In-Reply-To: Message-ID: <20050704152611.9065.qmail@web31507.mail.mud.yahoo.com> --- Markus Sch?pflin wrote: > Using gcc-3.4.3 and boost.python 1.32.0. Full example: > > ---%<--- > #include > #include > > typedef char bar_t[4]; Could you make it a boost::array? > struct foo > { > bar_t bar; > foo() { > bar[0] = 'b'; bar[1] = 'a'; > bar[2] = 'r'; bar[3] = 0; > } > }; > > BOOST_PYTHON_MODULE(test) > { > using namespace boost::python; > > class_("foo") > .def_readonly("bar", &foo::bar) > ; > } > --->%--- > > The compiles and links ok, but when using it from python I get the > following error: > > Python 2.3 (#1, Jul 30 2003, 14:14:00) > [GCC 3.3 20030226 (prerelease) (SuSE Linux)] on linux2 > Type "help", "copyright", "credits" or "license" for more information. > >>> from test import * > >>> print foo().bar > Traceback (most recent call last): > File "", line 1, in ? > TypeError: No to_python (by-value) converter found for C++ type: char [4] > > So I went ahead and added a custom converter for bar_t like so: > > struct bar_t_to_python_str > { > static PyObject* convert(bar_t const &s) Here bar_t is equivalent to a plain char*. The size information is lost. This due to the C heritage. > { > return boost::python::incref(boost::python::object(s).ptr()); > } > }; > > and in BOOST_PYTHON_MODULE(test): > > to_python_converter(); > > Is it to be expected that I do need a custom type converter for this? Or do > I miss something? You'd need a custom converter for boost::array if that is an option. The converter would also do the from_python conversion. If the C++ interface is fixed, you'd have to work with thin wrappers. As long as you stay exclusively within the framework of C++, as Boost.Python does, this is the only option. Cheers, Ralf __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From markus.schoepflin at comsoft.de Mon Jul 4 17:42:29 2005 From: markus.schoepflin at comsoft.de (=?ISO-8859-1?Q?Markus_Sch=F6pflin?=) Date: Mon, 04 Jul 2005 17:42:29 +0200 Subject: [C++-sig] [boost.python] char arrays in structs In-Reply-To: <20050704152611.9065.qmail@web31507.mail.mud.yahoo.com> References: <20050704152611.9065.qmail@web31507.mail.mud.yahoo.com> Message-ID: Ralf W. Grosse-Kunstleve wrote: > --- Markus Sch?pflin wrote: >>Using gcc-3.4.3 and boost.python 1.32.0. Full example: >> >>---%<--- >>#include >>#include >> >>typedef char bar_t[4]; > Could you make it a boost::array? Not really, because in reality it's an external fixed API. >>struct foo >>{ >> bar_t bar; >> foo() { >> bar[0] = 'b'; bar[1] = 'a'; >> bar[2] = 'r'; bar[3] = 0; >> } >>}; >> >>BOOST_PYTHON_MODULE(test) >>{ >> using namespace boost::python; >> >> class_("foo") >> .def_readonly("bar", &foo::bar) >> ; >>} >>--->%--- >> >>The compiles and links ok, but when using it from python I get the >>following error: >> >>Python 2.3 (#1, Jul 30 2003, 14:14:00) >>[GCC 3.3 20030226 (prerelease) (SuSE Linux)] on linux2 >>Type "help", "copyright", "credits" or "license" for more information. >> >>> from test import * >> >>> print foo().bar >>Traceback (most recent call last): >> File "", line 1, in ? >>TypeError: No to_python (by-value) converter found for C++ type: char [4] >> >>So I went ahead and added a custom converter for bar_t like so: >> >>struct bar_t_to_python_str >>{ >> static PyObject* convert(bar_t const &s) > > > Here bar_t is equivalent to a plain char*. The size information is lost. This > due to the C heritage. Duh, I keep forgetting about that. But this makes me wondering why the custom converter indeed does the trick in my example. > > >> { >> return boost::python::incref(boost::python::object(s).ptr()); >> } >>}; >> >>and in BOOST_PYTHON_MODULE(test): >> >> to_python_converter(); >> >>Is it to be expected that I do need a custom type converter for this? Or do >>I miss something? > You'd need a custom converter for boost::array if that is an option. > The converter would also do the from_python conversion. > > If the C++ interface is fixed, you'd have to work with thin wrappers. As long > as you stay exclusively within the framework of C++, as Boost.Python does, this > is the only option. You mean thin wrapper as follows? struct wrap_foo : public foo { char const *get_bar() { return bar; } }; and then class_("foo") .def_property("bar", &foo_derived::get_bar) ; > > Cheers, > Ralf Thanks, Markus From dave at boost-consulting.com Mon Jul 4 18:30:44 2005 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 04 Jul 2005 12:30:44 -0400 Subject: [C++-sig] [boost.python] char arrays in structs References: <20050704152611.9065.qmail@web31507.mail.mud.yahoo.com> Message-ID: "Ralf W. Grosse-Kunstleve" writes: > > Here bar_t is equivalent to a plain char*. The size information is lost. This > due to the C heritage. That's incorrect. -- Dave Abrahams Boost Consulting www.boost-consulting.com From rwgk at yahoo.com Mon Jul 4 18:34:57 2005 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Mon, 4 Jul 2005 09:34:57 -0700 (PDT) Subject: [C++-sig] In a C++ extension, how to use a C++ class exported in another extension In-Reply-To: Message-ID: <20050704163457.67879.qmail@web31503.mail.mud.yahoo.com> --- David Abrahams wrote: > > This solution is based on what I found in SWIG-1.3.24/Lib/python/pyrun.swg. > > At the heart of the solution is this simple fragment: > > > > static void* extract(PyObject* op) \ > > { \ > > if (std::strcmp(op->ob_type->tp_name, "PySwigObject") != 0) > > return 0; \ > > Isn't there a type object somewhere you can compare ob_type with? It seemed hard to me. Here is what I understand: SWIG is a wrapper generator (more similar to Pyste than to Boost.Python). In the SWIG-1.3.24/Examples/python/class that I was using, SWIG copies a big chunk of code into the generated example_wrap.cxx. This includes the complete definition of the type object for PySwigObject. The type definition is implemented as a group of static objects in this function: SWIGRUNTIME PyTypeObject* PySwigObject_GetType(); We'd have to get hold of this function, which I believe will complicate the linking severely. But even if we did, it wouldn't get us very far since each SWIG-generated extension has its own version of the type object, with its own address. That's probably why I found this function: SWIGRUNTIMEINLINE int PySwigObject_Check(PyObject *op) { return ((op)->ob_type == PySwigObject_GetType()) || (strcmp((op)->ob_type->tp_name,"PySwigObject") == 0); } I am still wondering why SWIG does "one or the other" and not simply the more general "other". The best explanation I can find for myself is optimization for speed (pointer equivalence vs. string comparison). Anyway, for me the conclusion was clear: it is definitely not worth complicating the build process for such a minute gain. If the Python/C++ combination is used sensibly the runtime difference will be unmeasurable anyway. > > PySwigObject* swig_obj_ptr = reinterpret_cast(op); \ > > This should be static_cast. I tried it but it doesn't work: g++ -fPIC -ftemplate-depth-120 -w -DBOOST_DISABLE_THREADS -DNDEBUG -O3 -ffast-math -DBOOST_PYTHON_MAX_BASES=2 -I/net/legless/scratch1/rwgk/dist/boost -I/usr/local_cci/Python-2.4.1_ticker_simple/include/python2.4 -c -o boost_adaptbx/swig_args_ext.os /net/legless/scratch1/rwgk/dist/boost_adaptbx/swig_args_ext.cpp /net/legless/scratch1/rwgk/dist/boost_adaptbx/swig_args_ext.cpp: In static member function `static void* boost::python::swig_arg::extract(PyObject*)': /net/legless/scratch1/rwgk/dist/boost_adaptbx/swig_args_ext.cpp:112: invalid static_cast from type `PyObject*' to type `PySwigObject*' /net/legless/scratch1/rwgk/dist/boost_adaptbx/swig_args_ext.cpp: In static member function `static void* boost::python::swig_arg::extract(PyObject*)': /net/legless/scratch1/rwgk/dist/boost_adaptbx/swig_args_ext.cpp:113: invalid static_cast from type `PyObject*' to type `PySwigObject*' > > if (std::strcmp(swig_obj_ptr->desc, "_p_" # T) != 0) return 0; \ > > Heh, so that's how they do it. Pretty lame, IMO. Hey, let's be politically correct: Pretty basic, at that level. They decided to put all their energy into a special parser, which clearly has some advantages if you have to deal a lot with C-style interfaces. E.g. the int* question is coming up a lot. > Well, inheritance > won't work; a swig-wrapped Derived won't be able to be passed where a > Base is expected. If that doesn't matter, it's fine. Is there a way to write something like: bases_of >(); > > boost_python_swig_args_ext.show(c.this) > > boost_python_swig_args_ext.show(s.this) > > You should have part of the test that shows non-matching types are > rejected. I figured rejection is tested since the overload resolution couldn't work otherwise. What exactly do you have in mind? > > David, would you want to include the core of swig_args_ext.cpp in, > > e.g., boost/python/swig_arg.h? I think it would be a valuable > > addition. There are many SWIG-wrapped libraries. People could easily > > use them while writing their own extensions with Boost.Python. > > Sounds great! Needs docs, of course ;-) Would you be happy with a page like I wrote for the pickle suite, linked from the main page, e.g. "SWIG interoperability"? But I still have a question. I don't really like the interface I came up with since it requires two steps: 1. BOOST_PYTHON_SWIG_ARG(Circle) 2. swig_arg(); It would be nicer if one could simply write swig_arg("Circle"); Is there any way this could be achieved? Actually, here is another question: would it be best to wait until Boost 1.33 is out? Cheers, Ralf __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From rwgk at yahoo.com Mon Jul 4 18:56:34 2005 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Mon, 4 Jul 2005 09:56:34 -0700 (PDT) Subject: [C++-sig] [boost.python] char arrays in structs In-Reply-To: Message-ID: <20050704165634.81204.qmail@web31501.mail.mud.yahoo.com> --- David Abrahams wrote: > "Ralf W. Grosse-Kunstleve" writes: > > > > > Here bar_t is equivalent to a plain char*. The size information is lost. > This > > due to the C heritage. > > That's incorrect. Oh, sorry. What is correct then? Why would I want to use "boost::array" instead of "typedef char[4]"? ____________________________________________________ Yahoo! Sports Rekindle the Rivalries. Sign up for Fantasy Football http://football.fantasysports.yahoo.com From dave at boost-consulting.com Mon Jul 4 18:58:11 2005 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 04 Jul 2005 12:58:11 -0400 Subject: [C++-sig] [boost.python] char arrays in structs References: Message-ID: Markus Sch?pflin writes: > Is it to be expected that I do need a custom type converter for this? Or do > I miss something? It's "expected" in the sense that I never thought of implementing automatic conversions for char arrays. It should be possible to do, although that would probably get me into the position of implementing generalized array conversions (e.g. from Python lists). It's a little bit messy and not something I can get to right away. -- Dave Abrahams Boost Consulting www.boost-consulting.com From rwgk at yahoo.com Mon Jul 4 19:12:07 2005 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Mon, 4 Jul 2005 10:12:07 -0700 (PDT) Subject: [C++-sig] [boost.python] char arrays in structs In-Reply-To: Message-ID: <20050704171207.34997.qmail@web31504.mail.mud.yahoo.com> --- Markus Sch?pflin wrote: > > Here bar_t is equivalent to a plain char*. The size information is lost. > This > > due to the C heritage. > > Duh, I keep forgetting about that. But this makes me wondering why the > custom converter indeed does the trick in my example. Sorry, David corrected me here. Apparently there is a difference between foo(char s[4]) and what you have. I wasn't aware of that. > You mean thin wrapper as follows? > > struct wrap_foo : public foo > { > char const *get_bar() { return bar; } > }; > > and then > > class_("foo") > .def_property("bar", &foo_derived::get_bar) > ; You don't have to use inheritance just to provide a wrapper. An unbound function will also work if the first argument is foo& or foo const& (and maybe even foo* etc., I am not sure): char const* get_bar(foo& self) { return foo.bar(); } Then: class("foo") .def("get_bar", get_bar) ; __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From rwgk at yahoo.com Mon Jul 4 19:25:29 2005 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Mon, 4 Jul 2005 10:25:29 -0700 (PDT) Subject: [C++-sig] In a C++ extension, how to use a C++ class exported in another extension In-Reply-To: <20050704034611.GA31236@BigDell> Message-ID: <20050704172529.10260.qmail@web31509.mail.mud.yahoo.com> --- Clark wrote: > Yes. But we can still emulate what SWIG does to make a C++ Object be a > Python Object, and then return it. I don't think it would be very hard if the SWIG license allows us to copy fragments from SWIG-1.3.24/Lib/python/python.swg. I didn't check the license, and I am not in a position to do the legwork... all I can offer is to add my swig_arg code to the boost tree. __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From foo.Clark at gmail.com Mon Jul 4 20:59:30 2005 From: foo.Clark at gmail.com (Clark) Date: Tue, 5 Jul 2005 02:59:30 +0800 Subject: [C++-sig] In a C++ extension, how to use a C++ class exported in another extension In-Reply-To: References: <20050630150541.GA12758@BigDell> <20050630211702.2749.qmail@web31505.mail.mud.yahoo.com> <20050704040736.GB31236@BigDell> Message-ID: <20050704185930.GA693@BigDell> On Mon, Jul 04, 2005 at 08:22:12AM -0400, David Abrahams wrote: > Clark writes: > > >> > >> Oh, I see; all Swig objects have the same type? > > Yes, they are all PySwigObject. > > Please try to leave a blank line above and below quoted material; > otherwise it's hard to pick out what you're saying. Thanks for your advice. Actually, I'm a mail list newbie at present. I think most of the people here are very kindly. They would like to help others for nothing. > > >> Well you need some way to identify the Python objects for which the > >> above statement is true, unless you want to forego all error checking > >> and just allow a crash if a Swig-wrapped Foo is passed where a > >> Swig-wrapped Bar is expected. > > Sometimes it's critical. > > Sometimes it's critical to... identify the Python objects for which > the above statement is true? Forego all error checking and allow a > crash? Something else? to extract a C++ "this" pointer from a SWIG-wrapped object. > > > For example, to paint on screen efficiently, we must use the DC's > > methods in C++ directly. But because usually the GUI or framework is > > written in Python, we can only get the DC as a Python Object. > > I don't see the connection between that scenario and anything we're > discussing. en... The GUI library I used is wxPython, which is wrapped by SWIG. And other parts of my program is wrapped by Boost.Python. I need extract a C++ pointer wxDC * from a wxPython's DC. > > -- > Dave Abrahams > Boost Consulting > www.boost-consulting.com > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig From dave at boost-consulting.com Mon Jul 4 22:59:37 2005 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 04 Jul 2005 16:59:37 -0400 Subject: [C++-sig] In a C++ extension, how to use a C++ class exported in another extension References: <20050704163457.67879.qmail@web31503.mail.mud.yahoo.com> Message-ID: "Ralf W. Grosse-Kunstleve" writes: > --- David Abrahams wrote: >> > This solution is based on what I found in SWIG-1.3.24/Lib/python/pyrun.swg. >> > At the heart of the solution is this simple fragment: >> > >> > static void* extract(PyObject* op) \ >> > { \ >> > if (std::strcmp(op->ob_type->tp_name, "PySwigObject") != 0) >> > return 0; \ >> >> Isn't there a type object somewhere you can compare ob_type with? > > It seemed hard to me. Here is what I understand: > > SWIG is a wrapper generator (more similar to Pyste than to Boost.Python). In > the SWIG-1.3.24/Examples/python/class that I was using, SWIG copies a big chunk > of code into the generated example_wrap.cxx. This includes the complete > definition of the type object for PySwigObject. The type definition is > implemented as a group of static objects in this function: > > SWIGRUNTIME PyTypeObject* > PySwigObject_GetType(); > > We'd have to get hold of this function, which I believe will complicate the > linking severely. But even if we did, it wouldn't get us very far since each > SWIG-generated extension has its own version of the type object, with its own > address. That's probably why I found this function: > > SWIGRUNTIMEINLINE int > PySwigObject_Check(PyObject *op) { > return ((op)->ob_type == PySwigObject_GetType()) > || (strcmp((op)->ob_type->tp_name,"PySwigObject") == 0); > } > > I am still wondering why SWIG does "one or the other" and not simply the more > general "other". The best explanation I can find for myself is optimization for > speed (pointer equivalence vs. string comparison). Anyway, for me the > conclusion was clear: it is definitely not worth complicating the build process > for such a minute gain. If the Python/C++ combination is used sensibly the > runtime difference will be unmeasurable anyway. You have grown very wise, O grasshopper. >> Heh, so that's how they do it. Pretty lame, IMO. > > Hey, let's be politically correct: Pretty basic, at that level. > They decided to put all their energy into a special parser, which > clearly has some advantages if you have to deal a lot with C-style > interfaces. E.g. the int* question is coming up a lot. You shall now be my master. >> Well, inheritance >> won't work; a swig-wrapped Derived won't be able to be passed where a >> Base is expected. If that doesn't matter, it's fine. > > Is there a way to write something like: > > bases_of >(); In principle, yes, but it would take some nontrivial coding. >> > boost_python_swig_args_ext.show(c.this) >> > boost_python_swig_args_ext.show(s.this) >> >> You should have part of the test that shows non-matching types are >> rejected. > > I figured rejection is tested since the overload resolution couldn't work > otherwise. Oh, are you testing overload resolution? If so, that's enough. > What exactly do you have in mind? > >> > David, would you want to include the core of swig_args_ext.cpp in, >> > e.g., boost/python/swig_arg.h? I think it would be a valuable >> > addition. There are many SWIG-wrapped libraries. People could easily >> > use them while writing their own extensions with Boost.Python. >> >> Sounds great! Needs docs, of course ;-) > > Would you be happy with a page like I wrote for the pickle suite, > linked from the main page, e.g. "SWIG interoperability"? Great! > But I still have a question. I don't really like the interface I came up with > since it requires two steps: > > 1. BOOST_PYTHON_SWIG_ARG(Circle) > > 2. swig_arg(); > > It would be nicer if one could simply write > > swig_arg("Circle"); > > Is there any way this could be achieved? Well of course! No need to build a specialization of swig_arg; the only thing you're doing with that specialzation is prepending "t" to the name. You can just build the string inside the swig_arg ctor. Are you sure you want to write "Circle" twice? Seems to me that BOOST_PYTHON_SWIG_ARG(Circle) might be better. > Actually, here is another question: would it be best to wait until Boost 1.33 > is out? We are in a main trunk feature-freeze, but doing it now on a branch would be better than waiting. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Mon Jul 4 23:01:08 2005 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 04 Jul 2005 17:01:08 -0400 Subject: [C++-sig] [boost.python] char arrays in structs References: <20050704165634.81204.qmail@web31501.mail.mud.yahoo.com> Message-ID: "Ralf W. Grosse-Kunstleve" writes: > --- David Abrahams wrote: > >> "Ralf W. Grosse-Kunstleve" writes: >> >> > >> > Here bar_t is equivalent to a plain char*. The size information is lost. >> This >> > due to the C heritage. >> >> That's incorrect. > > Oh, sorry. > What is correct then? The size information is not lost; the parameter type is char const(&)[4] > Why would I want to use "boost::array" instead of "typedef > char[4]"? I don't know; I never suggested that idea. Wasn't that your suggestion? -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Mon Jul 4 23:02:28 2005 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 04 Jul 2005 17:02:28 -0400 Subject: [C++-sig] [boost.python] char arrays in structs References: <20050704171207.34997.qmail@web31504.mail.mud.yahoo.com> Message-ID: "Ralf W. Grosse-Kunstleve" writes: >> You mean thin wrapper as follows? >> >> struct wrap_foo : public foo >> { >> char const *get_bar() { return bar; } >> }; >> >> and then >> >> class_("foo") >> .def_property("bar", &foo_derived::get_bar) >> ; > > You don't have to use inheritance just to provide a wrapper. In fact, it won't work in this case. You can't call a wrap_foo member function on a foo object. -- Dave Abrahams Boost Consulting www.boost-consulting.com From markus.schoepflin at comsoft.de Tue Jul 5 10:08:09 2005 From: markus.schoepflin at comsoft.de (=?ISO-8859-1?Q?Markus_Sch=F6pflin?=) Date: Tue, 05 Jul 2005 10:08:09 +0200 Subject: [C++-sig] [boost.python] char arrays in structs In-Reply-To: <20050704171207.34997.qmail@web31504.mail.mud.yahoo.com> References: <20050704171207.34997.qmail@web31504.mail.mud.yahoo.com> Message-ID: Ralf W. Grosse-Kunstleve wrote: > You don't have to use inheritance just to provide a wrapper. An unbound > function will also work if the first argument is foo& or foo const& (and maybe > even foo* etc., I am not sure): > > char const* > get_bar(foo& self) { return foo.bar(); } > > Then: > > class("foo") > .def("get_bar", get_bar) > ; Yes, this works nicely. Thanks. Markus From markus.schoepflin at comsoft.de Tue Jul 5 10:12:45 2005 From: markus.schoepflin at comsoft.de (=?ISO-8859-1?Q?Markus_Sch=F6pflin?=) Date: Tue, 05 Jul 2005 10:12:45 +0200 Subject: [C++-sig] [boost.python] char arrays in structs In-Reply-To: References: Message-ID: David Abrahams wrote: > Markus Sch?pflin writes: >> Is it to be expected that I do need a custom type converter for this? >> Or do I miss something? > It's "expected" in the sense that I never thought of implementing > automatic conversions for char arrays. Ok, that's what I wanted to know. > It should be possible to do, although that would probably get me into > the position of implementing generalized array conversions (e.g. from > Python lists). It's a little bit messy and not something I can get to > right away. But it would be a nice thing to have. ;-) Thanks, Markus From markus.schoepflin at comsoft.de Tue Jul 5 10:11:23 2005 From: markus.schoepflin at comsoft.de (=?ISO-8859-1?Q?Markus_Sch=F6pflin?=) Date: Tue, 05 Jul 2005 10:11:23 +0200 Subject: [C++-sig] [boost.python] char arrays in structs In-Reply-To: References: <20050704171207.34997.qmail@web31504.mail.mud.yahoo.com> Message-ID: David Abrahams wrote: > "Ralf W. Grosse-Kunstleve" writes: > > >>>You mean thin wrapper as follows? >>> >>>struct wrap_foo : public foo >>>{ >>> char const *get_bar() { return bar; } >>>}; >>> >>>and then >>> >>>class_("foo") >>> .def_property("bar", &foo_derived::get_bar) >>> ; >> >>You don't have to use inheritance just to provide a wrapper. > > In fact, it won't work in this case. You can't call a wrap_foo member > function on a foo object. In fact I wanted to write: struct wrap_foo : public foo { char const *get_bar() const { return bar; } }; ... class_("foo") .add_property("bar", &wrap_foo::get_bar) ; This works like a charm. Thanks, Markus From rwgk at yahoo.com Tue Jul 5 11:11:28 2005 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Tue, 5 Jul 2005 02:11:28 -0700 (PDT) Subject: [C++-sig] In a C++ extension, how to use a C++ class exported in another extension In-Reply-To: <20050704185930.GA693@BigDell> Message-ID: <20050705091128.53267.qmail@web31502.mail.mud.yahoo.com> --- Clark wrote: > en... The GUI library I used is wxPython, which is wrapped by SWIG. And > other parts of my program is wrapped by Boost.Python. I need extract a > C++ pointer wxDC * from a wxPython's DC. I have some interest in this, too. Just like you we are using both wxPython and Boost.Python. I just checked in a simplified version of my BOOST_PYTHON_SWIG_ARG() macro. Look here for revision 1.1 of swig_arg.hpp (it may take a couple of hours to show up, therefore I am also attaching the file): http://cvs.sourceforge.net/viewcvs.py/cctbx/boost_adaptbx/ Copy the file somewhere into your source tree (the license is BSD-style open source). #include "swig_arg.hpp" and write BOOST_PYTHON_SWIG_ARG(wxDC) somewhere in your module's init function. Simply .def() your functions with wxDC* arguments. In Python, pass dc.this to your wrapped function. See also swig_args_ext.cpp and tst_swig_args.py in the CVS directory above. Is this all you need? Or do you also want to pass wxDC* and other wx* objects to a function with a common base class as argument? That you could do easily with thin wrappers (one-liners), e.g.: void foo(wxObject* obj); void foo_dc(wxDC* obj) { foo(obj); } void foo_nb(wxNotebook* obj) { foo(obj); } In your init function: BOOST_PYTHON_SWIG_ARG(wxDC); BOOST_PYTHON_SWIG_ARG(wxNotebook); def("foo", foo_dc); def("foo", foo_nb); Cheers, Ralf ____________________________________________________ Yahoo! Sports Rekindle the Rivalries. Sign up for Fantasy Football http://football.fantasysports.yahoo.com -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: swig_arg.hpp URL: From rwgk at yahoo.com Tue Jul 5 11:14:30 2005 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Tue, 5 Jul 2005 02:14:30 -0700 (PDT) Subject: [C++-sig] [boost.python] char arrays in structs In-Reply-To: Message-ID: <20050705091430.7715.qmail@web31513.mail.mud.yahoo.com> --- David Abrahams wrote: > The size information is not lost; the parameter type is > > char const(&)[4] Interesting. I don't think I would have figured this out myself. Thanks! > > Why would I want to use "boost::array" instead of "typedef > > char[4]"? > > I don't know; I never suggested that idea. Wasn't that your > suggestion? Yes, because I didn't know about the char const(&)[4] trick. I played around a bit with char const(&)[N] conversions, starting with Markus' converter. I got both to_python and from_python conversions to work under Linux and Tru64 Unix. Here is the code if anyone is interested: http://cvs.sourceforge.net/viewcvs.py/cctbx/boost_adaptbx/char_array_ext.cpp?rev=1.1&view=auto For the records: I encountered two problems: - Under Redhat WS 3 (gcc 3.2.3) the char[4] converters work with -O0 -g, but not with -O3 -ffast-math. char[3] and char[5] work both with and without optimization. - It compiles but doesn't work under Windows. I don't know why; no time to investigate right now. At the moment I just wanted to find out if it works in principle. Cheers, Ralf __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From rwgk at yahoo.com Tue Jul 5 11:24:41 2005 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Tue, 5 Jul 2005 02:24:41 -0700 (PDT) Subject: [C++-sig] In a C++ extension, how to use a C++ class exported in another extension In-Reply-To: Message-ID: <20050705092441.7015.qmail@web31508.mail.mud.yahoo.com> --- David Abrahams wrote: > Well of course! No need to build a specialization of swig_arg; the > only thing you're doing with that specialzation is prepending "t" to > the name. You can just build the string inside the swig_arg ctor. > > Are you sure you want to write "Circle" twice? Seems to me that > > BOOST_PYTHON_SWIG_ARG(Circle) > > might be better. I was asking because I wasn't sure about a static template member being used from a static template member function. But now I am. See my other posting, or swig_arg.hpp revision 1.1 once it shows up: http://cvs.sourceforge.net/viewcvs.py/cctbx/boost_adaptbx/ It is so simple now I could explain it to my grandma. BTW: I've also tested under Tru64 Unix with cxx (to make sure my static member handling is kosher). > > Actually, here is another question: would it be best to wait until Boost > 1.33 > > is out? > > We are in a main trunk feature-freeze, but doing it now on a branch > would be better than waiting. Branch...? Shudder. I'll wait. If someone wants it now it is easy enough to get (link above). Cheers, Ralf __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From markus.schoepflin at comsoft.de Tue Jul 5 11:31:26 2005 From: markus.schoepflin at comsoft.de (=?ISO-8859-1?Q?Markus_Sch=F6pflin?=) Date: Tue, 05 Jul 2005 11:31:26 +0200 Subject: [C++-sig] [boost.python] char arrays in structs In-Reply-To: References: <20050704171207.34997.qmail@web31504.mail.mud.yahoo.com> Message-ID: Markus Sch?pflin wrote: > Ralf W. Grosse-Kunstleve wrote: > > >>You don't have to use inheritance just to provide a wrapper. An unbound >>function will also work if the first argument is foo& or foo const& (and maybe >>even foo* etc., I am not sure): >> >>char const* >>get_bar(foo& self) { return foo.bar(); } >> >>Then: >> >> class("foo") >> .def("get_bar", get_bar) >> ; I played with that a little and now I have: template char const *get(T const &self) { return self.*p; } class_("foo") .add_property("bar", get); I wonder if there is a way to somehow get rid of specifying char[4] and probably foo manually. Markus From danny280279 at netscape.net Tue Jul 5 13:15:19 2005 From: danny280279 at netscape.net (danny280279 at netscape.net) Date: Tue, 05 Jul 2005 07:15:19 -0400 Subject: [C++-sig] c + python interchangable? Message-ID: <331A084B.31EAC710.48B2A67E@netscape.net> hi all i know that c and python are closely interchangable, so I was wondering if there are any docs that could help me change python code over to c code. __________________________________________________________________ Switch to Netscape Internet Service. As low as $9.95 a month -- Sign up today at http://isp.netscape.com/register Netscape. Just the Net You Need. New! Netscape Toolbar for Internet Explorer Search from anywhere on the Web and block those annoying pop-ups. Download now at http://channels.netscape.com/ns/search/install.jsp From djowel at gmail.com Tue Jul 5 13:37:27 2005 From: djowel at gmail.com (Joel de Guzman) Date: Tue, 05 Jul 2005 19:37:27 +0800 Subject: [C++-sig] Wrapping std::vector In-Reply-To: <42C584A7.3030607@pecm.nl> References: <42C584A7.3030607@pecm.nl> Message-ID: <42CA70F7.9020903@boost-consulting.com> Paul Melis wrote: > Hello, > I have an abstract class and a std::vector<> of pointers to this class. > A routine in my c++ code fills a vector with objects of classes derived > from the abstract class. > I'd like to iterate over the vector in python and use each of the items > in the vector depending on the type of derived class. > [...] > > I suspect that boost.python will wrap the return value of returnList() > as a pointer to Abstract, without the possibility at runtime to look at > the actual object type. Is this something I would have to code by hand? > For example, by making a routine that takes a pointer to Abstract and > uses dynamic_cast<> to test which of the concrete classes the object > actually is from? Pardon the delay. It's been a while. I'm investigating the problem in more detail. I'll get back to you on this, ok? Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net From dave at boost-consulting.com Tue Jul 5 15:10:06 2005 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 05 Jul 2005 09:10:06 -0400 Subject: [C++-sig] In a C++ extension, how to use a C++ class exported in another extension References: <20050705092441.7015.qmail@web31508.mail.mud.yahoo.com> Message-ID: "Ralf W. Grosse-Kunstleve" writes: >> We are in a main trunk feature-freeze, but doing it now on a branch >> would be better than waiting. > > Branch...? Shudder. I'll wait. If someone wants it now it is easy > enough to get (link above). Why do people fear branching so? -- Dave Abrahams Boost Consulting www.boost-consulting.com From Yves_Secretan at inrs-ete.uquebec.ca Tue Jul 5 17:30:23 2005 From: Yves_Secretan at inrs-ete.uquebec.ca (Yves Secretan) Date: Tue, 5 Jul 2005 11:30:23 -0400 Subject: [C++-sig] Same opaque pointer used in 2 modules provoques an assertion error Message-ID: Hi, I have a container of pointers and would like to add pointers to this container from Python using an opaque pointer. Everything works fine if I have only one module, but if I split the code in more modules, I get a failed assertion message: File: registry.cpp Line: 161 Expression: slot ==0 and ignoring the exception: test.py:11: RuntimeWarning: to-Python converter for struct void_ * already registered; second conversion method ignored. My understanding is that each module tries to register a converter, and I could not find a way to prevent it. My environnement: boost-1.32.0; Python 2.3; msvc7.0 I join the simplest example I could build: data1.cpp is the first module; data2.cpp the second module; test.py should display the problem. Thanks for any help Yves --------------------------------------------------------------- Yves Secretan, Professeur INRS-ETE 490, rue de la Couronne Qu?bec, Qu?bec G1K 9A9 CANADA tel: (418) 654 38 48 fax: (418) 654 26 00 e-mail: Yves_Secretan at ete.inrs.ca --------------------------------------------------------------- -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: data1.cpp Type: application/octet-stream Size: 609 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: data2.cpp Type: application/octet-stream Size: 356 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: Jamfile Type: application/octet-stream Size: 583 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: test.py Type: application/octet-stream Size: 146 bytes Desc: not available URL: From dave at boost-consulting.com Tue Jul 5 17:59:22 2005 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 05 Jul 2005 11:59:22 -0400 Subject: [C++-sig] Same opaque pointer used in 2 modules provoques an assertion error References: Message-ID: "Yves Secretan" writes: > Hi, > > I have a container of pointers and would like to add pointers to this > container from Python using an opaque pointer. > Everything works fine if I have only one module, but if I split the code in > more modules, I get a failed assertion message: > File: registry.cpp > Line: 161 > Expression: slot ==0 > and ignoring the exception: > test.py:11: RuntimeWarning: to-Python converter for struct void_ * already > registered; second conversion method ignored. > > My understanding is that each module tries to register a converter, and I > could not find a way to prevent it. > > My environnement: boost-1.32.0; Python 2.3; msvc7.0 > > I join the simplest example I could build: data1.cpp is the first module; > data2.cpp the second module; test.py should display the problem. > > Thanks for any help > Yves I think this is a bug in the return value policy. Looking at it, each time you use it in a new module the converter will try to register itself. What happens when you stop using the return value policy and instead construct an opaque_pointer_converter("void_") in the first of the two modules to be loaded? Gottfried, http://www.boost.org/libs/python/doc/v2/opaque_pointer_converter.html refers me to http://www.boost.org/libs/python/doc/v2/return_opaque_pointer.html#example for an example, but there's no example of the use of opaque_pointer_converter there. What should we do about this? > --------------------------------------------------------------- > Yves Secretan, Professeur > INRS-ETE > 490, rue de la Couronne > Qu?bec, Qu?bec > G1K 9A9 CANADA > > tel: (418) 654 38 48 fax: (418) 654 26 00 > e-mail: Yves_Secretan at ete.inrs.ca > --------------------------------------------------------------- > > > #include > #include > > struct container > { > void add(void* p) { std::cerr << "Adding " << p << std::endl; } > }; > > struct data1 > { > }; > > struct void_; > BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(void_); > > void container_add(container& c, void_* p) > { > c.add((void*) p); > } > > void_* data1_asVoid(data1& d) > { > return (void_*)(&d); > } > > > BOOST_PYTHON_MODULE(data1) > { > using namespace boost::python; > > class_< container >("container") > .def("add", &container_add) > ; > > class_< data1 >("data1") > .def("asVoid", &data1_asVoid, return_value_policy< return_opaque_pointer >()) > ; > > } > > > #include > > struct data2 > { > }; > > struct void_; > BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(void_); > > void_* data2_asVoid(data2& d) > { > return (void_*)(&d); > } > > > BOOST_PYTHON_MODULE(data2) > { > using namespace boost::python; > > class_< data2 >("data2") > .def("asVoid", &data2_asVoid, return_value_policy< return_opaque_pointer >()) > ; > > } > > > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig -- Dave Abrahams Boost Consulting www.boost-consulting.com From rwgk at yahoo.com Tue Jul 5 18:45:51 2005 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Tue, 5 Jul 2005 09:45:51 -0700 (PDT) Subject: [C++-sig] In a C++ extension, how to use a C++ class exported in another extension In-Reply-To: Message-ID: <20050705164551.27288.qmail@web31514.mail.mud.yahoo.com> --- David Abrahams wrote: > "Ralf W. Grosse-Kunstleve" writes: > > >> We are in a main trunk feature-freeze, but doing it now on a branch > >> would be better than waiting. > > > > Branch...? Shudder. I'll wait. If someone wants it now it is easy > > enough to get (link above). > > Why do people fear branching so? Me: because I found it very difficult to branch individual files, and because clean incremental merging requires excessive tagging. I hope it is going to be a lot better with subversion. __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From ganssauge at gmx.de Tue Jul 5 18:55:47 2005 From: ganssauge at gmx.de (=?UTF-8?B?R290dGZyaWVkIEdhbsOfYXVnZQ==?=) Date: Tue, 05 Jul 2005 18:55:47 +0200 Subject: [C++-sig] Same opaque pointer used in 2 modules provoques an assertion error In-Reply-To: References: Message-ID: <42CABB93.3010405@gmx.de> David Abrahams writes: ... > > Gottfried, > http://www.boost.org/libs/python/doc/v2/opaque_pointer_converter.html > refers me to > http://www.boost.org/libs/python/doc/v2/return_opaque_pointer.html#example > for an example, but there's no example of the use of > opaque_pointer_converter there. What should we do about this? I can't say too much about the problem itself but the example definitely isn't missing but instead is referred to by a wrong name. Attached find a patch to correct it. Cheers, Gottfried -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: opaque_pointer_converter.html.patch URL: From grobinson at goombah.com Tue Jul 5 19:26:56 2005 From: grobinson at goombah.com (Gary Robinson) Date: Tue, 5 Jul 2005 13:26:56 -0400 Subject: [C++-sig] setup.py denies VS6 installed Message-ID: <20050705132656.161076.957b15bb@goombah.com> Hi, I have installed Visual Studio 6 on my XP box. I'm trying to build an extension with setup.py. When I enter python setup.py build at the command prompt, it says: error: Python was built with Version 6 of Visual Studio, and extensions need to be built with the same version of the compiler, but it isn't installed. As I said, it IS installed -- at least in the sense that I can bring up Visual Studio 6 from the Start menu. Also, the path variable contains Visual Studio stuff which I assume was put there by the installer. Any ideas for how I can get setup.py builds working on my machine? Thanks, Gary -- Gary Robinson CTO Emergent Music, LLC grobinson at goombah.com 207-942-3463 Company: http://www.goombah.com Blog: http://www.garyrobinson.net From jkankiewicz at advpubtech.com Tue Jul 5 20:35:25 2005 From: jkankiewicz at advpubtech.com (Jason Kankiewicz) Date: Tue, 05 Jul 2005 11:35:25 -0700 Subject: [C++-sig] c + python interchangable? In-Reply-To: <331A084B.31EAC710.48B2A67E@netscape.net> References: <331A084B.31EAC710.48B2A67E@netscape.net> Message-ID: They're interchangeable in a sense because Python is implemented in C and therefore any Python program must have an equivalent C implementation. They're not interchangeable in a sense because Python is an interpreted, dynamically-typed, garbage-collected language and not a compiled, statically-typed, non-garbage-collected language like C. Python complements C by addressing its weaknesses. Python's greatest weakness is speed but this can be addressed by re-coding the slowest parts of a Python program in C (or C++ using Boost.Python or SWIG) as an extension module. This "hybrid programming" approach should take much less work and yield similar results to re-coding an entire Python program in C. danny280279 at netscape.net wrote: > hi all i know that c and python are closely interchangable, so I was wondering if there are any docs that could help me change python code over to c code. > > __________________________________________________________________ > Switch to Netscape Internet Service. > As low as $9.95 a month -- Sign up today at http://isp.netscape.com/register > > Netscape. Just the Net You Need. > > New! Netscape Toolbar for Internet Explorer > Search from anywhere on the Web and block those annoying pop-ups. > Download now at http://channels.netscape.com/ns/search/install.jsp From grobinson at goombah.com Tue Jul 5 21:29:08 2005 From: grobinson at goombah.com (Gary Robinson) Date: Tue, 5 Jul 2005 15:29:08 -0400 Subject: [C++-sig] setup.py denies VS6 installed In-Reply-To: <20050705132656.161076.957b15bb@goombah.com> References: <20050705132656.161076.957b15bb@goombah.com> Message-ID: <20050705152908.462285.090398c3@goombah.com> > Any ideas for how I can get setup.py builds working on my machine? Never mind. I have it working now. Sorry for asking so many questions -- we're under an intense deadline here and so I'm swallowing my pride asking for help where I think it might save a lot of time. Hopefully when I know more I'll be able to contribute here myself. Gary -- Gary Robinson CTO Emergent Music, LLC grobinson at goombah.com 207-942-3463 Company: http://www.goombah.com Blog: http://www.garyrobinson.net From dave at boost-consulting.com Tue Jul 5 21:44:06 2005 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 05 Jul 2005 15:44:06 -0400 Subject: [C++-sig] Same opaque pointer used in 2 modules provoques an assertion error References: <42CABB93.3010405@gmx.de> Message-ID: Gottfried Gan?auge writes: > David Abrahams writes: > ... >> >> Gottfried, >> http://www.boost.org/libs/python/doc/v2/opaque_pointer_converter.html >> refers me to >> http://www.boost.org/libs/python/doc/v2/return_opaque_pointer.html#example >> for an example, but there's no example of the use of >> opaque_pointer_converter there. What should we do about this? > > I can't say too much about the problem itself but the example definitely > isn't missing but instead is referred to by a wrong name. It certainly is missing, if the example is supposed to show the user anything about opaque_pointer_converter. The only place that identifier is mentioned on the page is in a "See Also" section. > Attached find a patch to correct it. That doesn't really fix the problem I'm referring to. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Tue Jul 5 21:45:22 2005 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 05 Jul 2005 15:45:22 -0400 Subject: [C++-sig] setup.py denies VS6 installed References: <20050705132656.161076.957b15bb@goombah.com> Message-ID: Gary Robinson writes: > Hi, > > I have installed Visual Studio 6 on my XP box. > > I'm trying to build an extension with setup.py. > > When I enter > > python setup.py build > > at the command prompt, it says: > > error: Python was built with Version 6 of Visual Studio, > and extensions need to be built with the same version > of the compiler, but it isn't installed. This is a distutils question AFAICT. You should ask the provider of the specific setup.py script you're invoking. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Tue Jul 5 21:45:01 2005 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 05 Jul 2005 15:45:01 -0400 Subject: [C++-sig] setup.py denies VS6 installed References: <20050705132656.161076.957b15bb@goombah.com> Message-ID: Gary Robinson writes: > Hi, > > I have installed Visual Studio 6 on my XP box. > > I'm trying to build an extension with setup.py. > > When I enter > > python setup.py build > > at the command prompt, it says: > > error: Python was built with Version 6 of Visual Studio, > and extensions need to be built with the same version > of the compiler, but it isn't installed. This is a distutils question AFAICT. You should ask the provider of the specific setup.py script you're invoking. -- Dave Abrahams Boost Consulting www.boost-consulting.com From danny280279 at netscape.net Wed Jul 6 02:18:19 2005 From: danny280279 at netscape.net (danny280279 at netscape.net) Date: Tue, 05 Jul 2005 20:18:19 -0400 Subject: [C++-sig] c + python interchangable? Message-ID: <588965E5.0665FDA2.48B2A67E@netscape.net> Jason Kankiewicz wrote: >They're interchangeable in a sense because Python is implemented in C >and therefore any Python program must have an equivalent C >implementation. They're not interchangeable in a sense because Python is >an interpreted, dynamically-typed, garbage-collected language and not a >compiled, statically-typed, non-garbage-collected language like C. So what your saying is (code here:) #define DEBUG #include #include #include #include #include #include are static links to code comapred to def debug import import import because to me they seem the same, or am i just being stupid? if that's the case then are there any docs on hybrid programming, because then i could implement all of it in hybrid python/c. > >Python complements C by addressing its weaknesses. Python's greatest >weakness is speed but this can be addressed by re-coding the slowest >parts of a Python program in C (or C++ using Boost.Python or SWIG) as an >extension module. This "hybrid programming" approach should take much >less work and yield similar results to re-coding an entire Python >program in C. > my code for findfiles - this is to be renamed and reimplemented as search, a natural language command that can be integrated with package management software to do something like "search package install run". but this still doesn't do what the commands meant to: Search (the net) (find)Package Install(package) Run(package), type the name of a package in your browser and it comes up with a site that contains that package: this is a search for autotools (gnu) http://sources.redhat.com/autobook/ now if you could do that using the search command then you could get "search autotools install run" and it would directly go for the above url, query the site, download, and install the files, then run the application, actually here i think you get a docbook that can be run in yelp or something. #define DEBUG #include #include #include #include #include #include static ERROR CMDInit(OBJECTPTR, struct KernelBase *); static ERROR CMDExpunge(void); #define VER_FINDFILES 1.0 MODULE_HEADER = { MODULE_HEADER_V1, CMDInit, NULL, NULL, CMDExpunge, JMP_DEFAULT, 0, CPU_PC, VER_FINDFILES, VER_KERNEL, "", "", "", "" }; static struct KernelBase *KernelBase; static struct FileSystemBase *FileSystemBase; static struct StringsBase *StringsBase; static OBJECTPTR modFile = NULL, modStrings = NULL; static OBJECTPTR FindFilesClass = NULL; static FIELD FID_SrcFile, FID_DestFile; struct FindFiles { OBJECT_HEADER OBJECTID OutputID; LONG Static; LONG Operation; LONG Response; LONG Flags; PRIVATE_FIELDS UBYTE Location[300]; UBYTE Filter[40]; UBYTE Content[60]; UBYTE prvFile[160]; UBYTE Dest[300]; BYTE Stop; LONG TotalChildren; STRING ConfirmScript; STRING ErrorScript; UBYTE *DataBuffer; struct ChildEntry ChildList[10]; }; enum { FOP_NONE=0, FOP_COPY, FOP_MOVE, FOP_DELETE }; enum { RSP_NONE=0, RSP_CANCEL, RSP_YES, RSP_YESALL, RSP_NO }; static ERROR GET_ConfirmScript(struct FindFiles *, STRING *); static ERROR GET_Dest(struct FindFiles *, STRING *); static ERROR GET_ErrorScript(struct FindFiles *, STRING *); static ERROR GET_File(struct FindFiles *, STRING *); static ERROR GET_FileContent(struct FindFiles *, STRING *); static ERROR GET_Filter(struct FindFiles *, STRING *); static ERROR GET_Location(struct FindFiles *, STRING *); static ERROR SET_ConfirmScript(struct FindFiles *, STRING); static ERROR SET_Dest(struct FindFiles *, STRING); static ERROR SET_ErrorScript(struct FindFiles *, STRING); static ERROR SET_FileContent(struct FindFiles *, STRING); static ERROR SET_Filter(struct FindFiles *, STRING); static ERROR SET_Location(struct FindFiles *, STRING); #define FF_FORCEDIR 0x00000001 #define FF_INCLUDEROOT 0x00000002 #define FF_XML 0x00000004 #define FF_NOACTIVATE 0x00000008 #define FF_SCANLINKS 0x00000010 #define FF_MATCHFOLDERS 0x00000020 #define FF_IGNOREFILES 0x00000040 static struct FieldDef FindFlags[] = { { "FORCEDIR", FF_FORCEDIR }, { "INCLUDEROOT", FF_INCLUDEROOT }, { "XML", FF_XML }, { "NOACTIVATE", FF_NOACTIVATE }, { "SCANLINKS", FF_SCANLINKS }, { "MATCHFOLDERS", FF_MATCHFOLDERS }, { "IGNOREFILES", FF_IGNOREFILES }, { NULL, NULL } }; static struct FieldDef OperationLookup[] = { { "NONE", NULL }, { "COPY", FOP_COPY }, { "MOVE", FOP_MOVE }, { "DELETE", FOP_DELETE }, { NULL, NULL } }; static struct FieldDef ResponseLookup[] = { { "CANCEL", RSP_CANCEL }, { "YES", RSP_YES }, { "YESALL", RSP_YESALL }, { "NO", RSP_NO }, { "NOALL", RSP_CANCEL }, { NULL, NULL } }; static struct FieldArray FindFilesFields[] = { { "Output", 0, FDF_OBJECTID|FDF_RW, 0, NULL, NULL }, { "Static", 0, FDF_LONG|FDF_RW, 0, NULL, NULL }, { "Operation", 0, FDF_LONG|FDF_LOOKUP|FDF_RW, (LONG)&OperationLookup, NULL, NULL }, { "Response", 0, FDF_LONG|FDF_LOOKUP|FDF_RW, (LONG)&ResponseLookup, NULL, NULL }, { "Flags", 0, FDF_LONGFLAGS|FDF_RW, (LONG)&FindFlags, NULL, NULL }, { "ConfirmScript", 0, FDF_STRING|FDF_RW, 0, GET_ConfirmScript, SET_ConfirmScript }, { "Dest", 0, FDF_STRING|FDF_RW, 0, GET_Dest, SET_Dest }, { "ErrorScript", 0, FDF_STRING|FDF_RW, 0, GET_ErrorScript, SET_ErrorScript }, { "File", 0, FDF_STRING|FDF_R, 0, GET_File, NULL }, { "FileContent", 0, FDF_STRING|FDF_RW, 0, GET_FileContent, SET_FileContent }, { "Filter", 0, FDF_STRING|FDF_RW, 0, GET_Filter, SET_Filter }, { "Location", 0, FDF_STRING|FDF_RW, 0, GET_Location, SET_Location }, { "Src", 0, FDF_STRING|FDF_RW, 0, GET_Location, SET_Location }, END_FIELD }; static ERROR FIND_Activate(struct FindFiles *, APTR); static ERROR FIND_ClosingTag(struct FindFiles *, APTR); static ERROR FIND_Deactivate(struct FindFiles *, APTR); static ERROR FIND_Free(struct FindFiles *, APTR); static ERROR FIND_Init(struct FindFiles *, APTR); static struct ActionArray FindFilesActions[] = { { AC_Activate, FIND_Activate }, { AC_ClosingTag, FIND_ClosingTag }, { AC_Deactivate, FIND_Deactivate }, { AC_Free, FIND_Free }, { AC_Init, FIND_Init }, { NULL, NULL } }; #define MT_AddLocation -1 struct mtAddLocation { STRING Location; }; static struct FunctionField argsAddLocation[] = { { "Location", ARG_STRING }, { NULL, NULL } }; static ERROR FIND_AddLocation(struct FindFiles *, struct mtAddLocation *); static struct MethodArray FindFilesMethods[] = { { MT_AddLocation, FIND_AddLocation, "AddLocation", argsAddLocation, sizeof(struct mtAddLocation) }, { NULL, NULL, NULL, NULL } }; static LONG ContentMatch(struct FindFiles *, STRING, STRING, UBYTE *); static void FileMatched(struct FindFiles *, STRING, STRING, OBJECTPTR, struct DirInfo *); static void OutputText(struct FindFiles *, STRING); static void ScanLocation(struct FindFiles *, STRING, OBJECTPTR); static void UserConfirmation(struct FindFiles *, STRING, STRING); static void UserError(struct FindFiles *, STRING, ERROR); static ERROR FileCopy(struct FindFiles *, STRING, STRING); static ERROR FileDelete(struct FindFiles *, STRING); static ERROR FileMove(struct FindFiles *, STRING, STRING); static BYTE FindFilesUsage[] = { "USAGE: findfiles [src]=filename [content]=filecontent [filter]=namefilter\n\ \n\ Use the FindFiles command to search for files in your system. At a minimum you should supply the directory location from which you wish to start the search. Optionally you can also search on file content and filter on file names. Here is an example that searches for PNG files:\n\ \n\ findfiles src=athene:pictures/ filter=*.png\n\ \n\ If you do not specify the starting location, the search will start from the home: location." }; static ERROR CMDInit(OBJECTPTR argModule, struct KernelBase *argKernelBase) { KernelBase = argKernelBase; if (CreateObject(ID_MODULE, NULL, &modStrings, NULL, FID_Name|TSTRING, "strings", FID_Version|TFLOAT, MODVERSION_STRINGS, TAGEND) IS ERR_Okay) { if (GetField(modStrings, FID_ModBase, FT_POINTER, &StringsBase) != ERR_Okay) { return(ObjectError(argModule, ERH_InitModule, ERR_GetField)); } } else return(ObjectError(argModule, ERH_InitModule, ERR_CreateObject)); if (CreateObject(ID_MODULE, NULL, &modFile, NULL, FID_Name|TSTRING, "filesystem", FID_Version|TFLOAT, MODVERSION_FILESYSTEM, TAGEND) IS ERR_Okay) { if (GetField(modFile, FID_ModBase, FT_POINTER, &FileSystemBase) != ERR_Okay) { return(ObjectError(argModule, ERH_InitModule, ERR_GetField)); } } else return(ObjectError(argModule, ERH_InitModule, ERR_CreateObject)); ResolveFields("SrcFile", &FID_SrcFile, "DestFile", &FID_DestFile, TAGEND); return(CreateObject(ID_CLASS, NULL, (OBJECTPTR *)&FindFilesClass, NULL, FID_BaseClassID|TLONG, ID_FINDFILES, FID_Version|TFLOAT, VER_FINDFILES, FID_Name|TSTRING, "FindFiles", FID_Category|TLONG, CCF_COMMAND, FID_Usage|TSTRING, FindFilesUsage, FID_Actions|TPTR, FindFilesActions, FID_Methods|TPTR, FindFilesMethods, FID_Fields|TPTR, FindFilesFields, FID_Size|TLONG, sizeof(struct FindFiles), TAGEND)); } static ERROR CMDExpunge(void) { if (FindFilesClass) { acFree(FindFilesClass); FindFilesClass = NULL; } if (modFile) { acFree(modFile); modFile = NULL; } if (modStrings) { acFree(modStrings); modStrings = NULL; } return(ERR_Okay); } static BYTE IsDirectory(STRING Path) { WORD i; if (!Path) return(FALSE); for (i=0; Path[i]; i++); if ((Path[i-1] IS '/') OR (Path[i-1] IS '\\') OR (Path[i-1] IS ':')) return(TRUE); return(FALSE); } #define BUFFER_SIZE 4096 static ERROR FIND_Activate(struct FindFiles *Self, APTR Void) { struct DirInfo list; OBJECTPTR output; STRING buffer; ERROR error; WORD len, i, k; if (!Self->Location) { if (SetField(Self, FID_Location, FT_STRING, "athene:") != ERR_Okay) { OutputText(Self, "Error: You have not given me a location."); return(ERR_FieldNotSet); } } if (Self->TotalChildren IS -1) { Self->TotalChildren = ARRAYSIZE(Self->ChildList); ListChildren(Self->Head.UniqueID, Self->ChildList, &Self->TotalChildren); } if (!Self->Response) Self->Response = RSP_YES; else { if (Self->Response IS RSP_CANCEL) return(ERR_Okay); } if ((Self->Operation IS FOP_DELETE) AND (Self->ConfirmScript)) { if (Self->Response != RSP_YESALL) { UserConfirmation(Self, Self->Location, Self->Location); } if ((Self->Response != RSP_YES) AND (Self->Response != RSP_YESALL)) { DPrintF("FindFiles:","User cancelled deletion of this file - response %d.", Self->Response); return(ERR_Okay); } } output = NULL; if (Self->OutputID) { if (AccessObject(Self->OutputID, 3000, &output) != ERR_Okay) { return(ObjectError(Self, ERH_Activate, ERR_AccessObject)); } Action(AC_Clear, output, NULL); } DPrintF("~Activate()","[FindFiles:%d] Filter: %s, Location: %s, Content: %s, Operation: %s", GetUniqueID(Self), Self->Filter, Self->Location, Self->Content, OperationLookup[Self->Operation]); if (AllocMemory(BUFFER_SIZE, MEM_STRING|MEM_NOCLEAR, (APTR *)&buffer, NULL) IS ERR_Okay) { if (AllocMemory(BUFFER_SIZE, MEM_STRING|MEM_NOCLEAR, (APTR *)&Self->DataBuffer, NULL) IS ERR_Okay) { Self->Stop = FALSE; error = ERR_Okay; for (len=0; Self->Location[len]; len++) buffer[len] = Self->Location[len]; buffer[len] = 0; if (IsDirectory(Self->Location) IS TRUE) { k = StrLength(Self->Dest); if (Self->Flags & FF_INCLUDEROOT) { if ((buffer[len-1] IS '/') OR (buffer[len-1] IS '\\')) { i = len-1; while ((i > 0) AND (buffer[i-1] != ':') AND (buffer[i-1] != '/') AND (buffer[i-1] != '\\')) i--; StrCopy(buffer+i, Self->Dest+k, sizeof(Self->Dest)-k); } } #ifndef DEBUG DebugState(FALSE, -1); #endif ScanLocation(Self, buffer, output); #ifndef DEBUG DebugState(TRUE, -1); #endif Self->Dest[k] = 0; } else { while ((len > 0) AND (buffer[len-1] != '/') AND (buffer[len-1] != ':') AND (buffer[len-1] != '\\')) len--; if ((!Self->Filter[0]) OR (StrCompare(Self->Filter, buffer+len, 0, STR_WILDCARD) IS ERR_Okay)) { if (ContentMatch(Self, buffer, Self->Content, Self->DataBuffer) IS TRUE) { UBYTE filename[256]; StrCopy(buffer+len, filename, sizeof(filename)); buffer[len] = 0; ClearMemory(&list, sizeof(list)); FileMatched(Self, buffer, filename, output, &list); } } } FreeMemory(Self->DataBuffer); Self->DataBuffer = NULL; } else error = ObjectError(Self, ERH_Activate, ERR_AllocMemory); FreeMemory(buffer); } else error = ObjectError(Self, ERH_Activate, ERR_AllocMemory); if (output) ReleaseObject(output); StepBack(); return(error); } static ERROR FIND_AddLocation(struct FindFiles *Self, struct mtAddLocation *Args) { if ((!Args) OR (!Args->Location)) return(ERR_Args); return(ERR_Okay); } static ERROR FIND_ClosingTag(struct FindFiles *Self, APTR Void) { Self->TotalChildren = ARRAYSIZE(Self->ChildList); ListChildren(Self->Head.UniqueID, Self->ChildList, &Self->TotalChildren); if (Self->Static IS FALSE) { Action(AC_Activate, Self, NULL); Action(AC_Free, Self, NULL); } return(ERR_Okay); } static ERROR FIND_Deactivate(struct FindFiles *Self, APTR Void) { Self->Stop = TRUE; return(ERR_Okay); } static ERROR FIND_Free(struct FindFiles *Self, APTR Void) { if (Self->ConfirmScript) { FreeMemory(Self->ConfirmScript); Self->ConfirmScript = NULL; } if (Self->ErrorScript) { FreeMemory(Self->ErrorScript); Self->ErrorScript = NULL; } return(ERR_Okay); } static ERROR FIND_Init(struct FindFiles *Self, APTR Void) { Self->TotalChildren = -1; return(ERR_Okay); } static ERROR GET_ConfirmScript(struct FindFiles *Self, STRING *Value) { if ((*Value = Self->ConfirmScript)) { *Value = Self->ConfirmScript; return(ERR_Okay); } else return(ERR_FieldNotSet); return(ERR_Okay); } static ERROR SET_ConfirmScript(struct FindFiles *Self, STRING Value) { LONG i; if (Self->ConfirmScript) { FreeMemory(Self->ConfirmScript); Self->ConfirmScript = NULL; } if ((Value) AND (*Value)) { for (i=0; Value[i]; i++); if (AllocMemory(i+1, MEM_STRING|MEM_NOCLEAR, (void **)&Self->ConfirmScript, NULL) IS ERR_Okay) { for (i=0; Value[i]; i++) Self->ConfirmScript[i] = Value[i]; Self->ConfirmScript[i] = 0; return(ERR_Okay); } else return(ObjectError(Self, ERH_SetField, ERR_AllocMemory)); } return(ERR_Okay); } static ERROR GET_Dest(struct FindFiles *Self, STRING *Value) { if (Self->Dest[0]) { *Value = Self->Dest; return(ERR_Okay); } else return(ERR_FieldNotSet); } static ERROR SET_Dest(struct FindFiles *Self, STRING Value) { WORD i; if (Value) { for (i=0; (i < sizeof(Self->Dest)-1) AND (Value[i]); i++) Self->Dest[i] = Value[i]; Self->Dest[i] = 0; } else Self->Dest[0] = 0; return(ERR_Okay); } static ERROR GET_ErrorScript(struct FindFiles *Self, STRING *Value) { if ((*Value = Self->ErrorScript)) { *Value = Self->ErrorScript; return(ERR_Okay); } else return(ERR_FieldNotSet); } static ERROR SET_ErrorScript(struct FindFiles *Self, STRING Value) { LONG i; if (Self->ErrorScript) { FreeMemory(Self->ErrorScript); Self->ErrorScript = NULL; } if ((Value) AND (*Value)) { for (i=0; Value[i]; i++); if (AllocMemory(i+1, MEM_STRING|MEM_NOCLEAR, (void **)&Self->ErrorScript, NULL) IS ERR_Okay) { for (i=0; Value[i]; i++) Self->ErrorScript[i] = Value[i]; Self->ErrorScript[i] = 0; return(ERR_Okay); } else return(ObjectError(Self, ERH_SetField, ERR_AllocMemory)); } return(ERR_Okay); } static ERROR GET_File(struct FindFiles *Self, STRING *Value) { if ((*Value = Self->prvFile)) return(ERR_Okay); else return(ERR_FieldNotSet); } static ERROR GET_FileContent(struct FindFiles *Self, STRING *Value) { if (Self->Content[0]) { *Value = Self->Content; return(ERR_Okay); } else { *Value = NULL; return(ERR_FieldNotSet); } } static ERROR SET_FileContent(struct FindFiles *Self, STRING Value) { WORD i; if (Value) { for (i=0; (i < sizeof(Self->Content)-1) AND (Value[i]); i++) Self->Content[i] = Value[i]; Self->Content[i] = 0; } else Self->Content[0] = 0; return(ERR_Okay); } static ERROR GET_Filter(struct FindFiles *Self, STRING *Value) { if (Self->Filter[0]) { *Value = Self->Filter; return(ERR_Okay); } else { *Value = NULL; return(ERR_FieldNotSet); } } static ERROR SET_Filter(struct FindFiles *Self, STRING Value) { WORD i; if (Value) { for (i=0; (i < sizeof(Self->Filter)-1) AND (Value[i]); i++) Self->Filter[i] = Value[i]; Self->Filter[i] = 0; } else Self->Filter[0] = 0; return(ERR_Okay); } static ERROR GET_Location(struct FindFiles *Self, STRING *Value) { if (Self->Location[0]) { *Value = Self->Location; return(ERR_Okay); } else { *Value = NULL; return(ERR_FieldNotSet); } return(ERR_Okay); } static ERROR SET_Location(struct FindFiles *Self, STRING Value) { WORD i; if ((Value) AND (*Value)) { for (i=0; (i < sizeof(Self->Location)-2) AND (Value[i]); i++) Self->Location[i] = Value[i]; if (Self->Flags & FF_FORCEDIR) if ((Value[i-1] != '/') AND (Value[i-1] != ':') AND (Value[i-1] != '\\')) Self->Location[i++] = '/'; Self->Location[i] = 0; } else Self->Location[0] = 0; return(ERR_Okay); } static void OutputText(struct FindFiles *Self, STRING Buffer) { struct acDataChannel channel; if (Self->OutputID) { /*** Send the data to the output object ***/ ActionMsg(AC_Clear, Self->OutputID, NULL); channel.ObjectID = GetUniqueID(Self); channel.DataType = DATA_TEXT; channel.Version = 1; channel.TotalEntries = 1; channel.Buffer = Buffer; channel.Size = StrLength(Buffer) + 1; ActionMsg(AC_DataChannel, Self->OutputID, &channel); } } static LONG ContentMatch(struct FindFiles *Self, STRING Location, STRING Content, UBYTE *DataBuffer) { struct acRead read; struct File *file; LONG size; WORD k, j; if ((!Content) OR (!*Content)) return(TRUE); if (CreateObject(ID_FILE, NULL, &file, NULL, FID_Location|TSTRING, Location, FID_Flags|TLONG, FL_READ, TAGEND) IS ERR_Okay) { if ((file->Flags & FL_SYMLINK) AND (!(Self->Flags & FF_SCANLINKS))) { acFree(file); return(FALSE); } GetField(file, FID_Size, FT_LONG, &size); k = 0; while (size > 0) { read.Buffer = DataBuffer; if (size < BUFFER_SIZE) read.Length = size; else read.Length = BUFFER_SIZE; Action(AC_Read, file, &read); for (j=0; (j < size) AND (j < BUFFER_SIZE); j++) { if (lcase(DataBuffer[j]) != lcase(Content[k])) k = 0; else { k++; if (!Content[k]) { acFree(file); return(TRUE); } } } ProcessMessages(NULL, NULL); if (Self->Stop IS TRUE) break; size -= BUFFER_SIZE; } acFree(file); } return(FALSE); } static void FileMatched(struct FindFiles *Self, STRING Path, STRING Filename, OBJECTPTR Output, struct DirInfo *Info) { UBYTE buffer[256]; OBJECTPTR object; WORD j, pathlen, filelen, fullpath_len; for (pathlen=0; Path[pathlen]; pathlen++); for (filelen=0; Filename[filelen]; filelen++); fullpath_len = StrCopy(Path, Self->prvFile, sizeof(Self->prvFile)); StrCopy(Filename, Self->prvFile + fullpath_len, sizeof(Self->prvFile) - fullpath_len); if (Output) { if (Self->Flags & FF_XML) { StrFormat(buffer, sizeof(buffer), "%s%s%d%4d%2d%2d %d:%d:%d", GetFileIcon(Self->prvFile), Filename, Path, (LONG)Info->Size, (LONG)Info->Size, Info->Time.Year, Info->Time.Month, Info->Time.Day, Info->Time.Hour, Info->Time.Minute, Info->Time.Second); ActionTags(AC_DataChannel, Output, Self->Head.UniqueID, DATA_XML, 1, buffer, StrLength(buffer)+1, 1); } else ActionTags(AC_DataChannel, Output, Self->Head.UniqueID, DATA_TEXT, 1, Self->prvFile, StrLength(Self->prvFile) + 1, 1); } if ((Self->TotalChildren > 0) AND (!(Self->Flags & FF_NOACTIVATE))) { for (j=0; j < Self->TotalChildren; j++) { if (AccessObject(Self->ChildList[j].ObjectID, 0, &object) IS ERR_Okay) { acActivate(object); ReleaseObject(object); } } } if (Self->Operation) { switch (Self->Operation) { case FOP_DELETE: FileDelete(Self, Self->prvFile); break; case FOP_COPY: FileCopy(Self, Self->prvFile, Filename); break; case FOP_MOVE: FileMove(Self, Self->prvFile, Filename); break; } } } static void ScanLocation(struct FindFiles *Self, STRING Buffer, OBJECTPTR output) { struct DirInfo *info; LONG k, bufferlen, count, flags; WORD root, len, insert, dest_created; ERROR error; if (Self->Dest[0]) DPrintF("ScanLocation()","%s TO %s", Buffer, Self->Dest); else DPrintF("ScanLocation()","%s", Buffer); if ((Buffer[0] IS ':') OR (!Buffer[0])) root = TRUE; else root = FALSE; if (Self->Stop IS TRUE) return; for (len=0; Buffer[len]; len++); count = 0; dest_created = FALSE; flags = RDF_FILE|RDF_SIZE|RDF_DATE|RDF_PERMISSIONS; if (Self->Flags & FF_MATCHFOLDERS) flags |= RDF_DIRECTORY|RDF_QUALIFY; if (Self->Flags & FF_IGNOREFILES) flags &= ~RDF_FILE; if (OpenDirectory(Buffer, flags, &info) IS ERR_Okay) { while (ScanDirectory(info) IS ERR_Okay) { count++; ProcessMessages(NULL, NULL); for (k=0; info->Name[k]; k++) Buffer[len+k] = info->Name[k]; Buffer[len+k] = 0; bufferlen = len+k; if (StrCompare(Self->Filter, info->Name, 0, STR_WILDCARD) != ERR_Okay) { #ifdef DEBUG DPrintF("ScanDir:","File \"%s\" does not match filter \"%s\"", info->Name, Self->Filter); #endif continue; } if (info->Flags & RDF_FILE) { if (ContentMatch(Self, Buffer, Self->Content, Self->DataBuffer) IS FALSE) { #ifdef DEBUG DPrintF("ScanDir:","Content of file %s is not a match.", info->Name); #endif continue; } } if (Self->Operation IS FOP_MOVE) { if (dest_created IS FALSE) { dest_created = TRUE; if (IsDirectory(Self->Dest)) MakeDirectory(Self->Dest, info->Permissions | PERMIT_USER); } } Buffer[len] = 0; FileMatched(Self, Buffer, info->Name, output, info); if (Self->Response IS RSP_CANCEL) Self->Stop = TRUE; if (Self->Stop IS TRUE) break; } Buffer[len] = 0; CloseDirectory(info); } if (Self->Stop IS TRUE) { #ifdef DEBUG DPrintF("ScanDirectory:","Stopping search."); #endif return; } if (OpenDirectory(Buffer, RDF_DIRECTORY|RDF_QUALIFY, &info) IS ERR_Okay) { insert = -1; if (Self->Dest[0]) { for (insert=0; Self->Dest[insert]; insert++); if ((Self->Dest[insert-1] != '/') AND (Self->Dest[insert-1] != '\\') AND (Self->Dest[insert-1] != ':')) { insert = -1; } } while (ScanDirectory(info) IS ERR_Okay) { count++; if (info->Flags & RDF_LINK) continue; ProcessMessages(NULL, NULL); if (root IS TRUE) { for (k=0; info->Name[k]; k++) Buffer[k] = info->Name[k]; Buffer[k] = 0; } else { for (k=0; info->Name[k]; k++) Buffer[len+k] = info->Name[k]; Buffer[len+k] = 0; } if (insert != -1) { StrCopy(info->Name, Self->Dest+insert, sizeof(Self->Dest) - insert); } ScanLocation(Self, Buffer, output); if (Self->Stop IS TRUE) break; if (insert != -1) Self->Dest[insert] = 0; } CloseDirectory(info); } #ifdef DEBUG else DPrintF("ScanDirectory()","No folders in %s", Buffer); #endif Buffer[len] = 0; if ((!count) AND ((Self->Operation IS FOP_COPY) OR (Self->Operation IS FOP_MOVE))) { if (IsDirectory(Self->Dest)) { BYTE save; for (len=0; Self->Dest[len]; len++); save = Self->Dest[len-1]; Self->Dest[len-1] = 0; //DPrintF("ScanDirectory:","Empty dir \"%s\" TO \"%s\"", Buffer, Self->Dest); if (Self->Operation IS FOP_COPY) error = CopyLocation(Buffer, Self->Dest); else error = MoveLocation(Buffer, Self->Dest); Self->Dest[len-1] = save; if (error != ERR_Okay) { DPrintF("ScanDirectory:","Error %d returned.", error); Self->Stop = TRUE; Self->Response = RSP_CANCEL; UserError(Self, Buffer, error); return; } } ProcessMessages(NULL, NULL); } else { if ((Self->Operation IS FOP_DELETE) AND (!Self->Filter[0]) AND (!Self->Content[0])) { DeleteFile(Buffer); } else if ((Self->Operation IS FOP_MOVE) AND (!Self->Filter[0]) AND (!Self->Content[0])) { DeleteFile(Buffer); } if (!count) ProcessMessages(NULL, NULL); } } static ERROR FileCopy(struct FindFiles *Self, STRING Location, STRING File) { UBYTE dest[300]; LONG type; ERROR error; WORD i; if (!Self->Dest[0]) return(ERR_Okay); i = StrCopy(Self->Dest, dest, sizeof(dest)-1); if ((dest[i-1] IS '/') OR (dest[i-1] IS '\\') OR (dest[i-1] IS ':')) { i += StrCopy(File, dest+i, sizeof(dest)-i); } if ((Self->ConfirmScript) AND (Self->Response != RSP_YESALL)) { if ((AnalyseLocation(dest, &type) IS ERR_Okay) AND ((type IS LOC_FILE) OR (type IS LOC_DIRECTORY))) { UserConfirmation(Self, Location, dest); } } if ((Self->Response != RSP_YES) AND (Self->Response != RSP_YESALL)) { DPrintF("FindFiles:","Skipping file %s, response %d", Location, Self->Response); return(ERR_Okay); } error = CopyLocation(Location, dest); if (error) { Self->Stop = TRUE; Self->Response = RSP_CANCEL; UserError(Self, Location, error); } return(ERR_Okay); } static ERROR FileDelete(struct FindFiles *Self, STRING Location) { ERROR error; if ((Self->Response IS RSP_CANCEL) OR (Self->Stop IS TRUE)) return(ERR_Okay); error = DeleteFile(Location); if (error) UserError(Self, Location, error); return(ERR_Okay); } static ERROR FileMove(struct FindFiles *Self, STRING Location, STRING File) { UBYTE dest[300]; LONG type; ERROR error; WORD i; DPrintF("FileMove()","%s, File: %s", Location, File); if (!Self->Dest[0]) return(ERR_Okay); i = StrCopy(Self->Dest, dest, sizeof(dest)-1); if ((dest[i-1] IS '/') OR (dest[i-1] IS '\\') OR (dest[i-1] IS ':')) { i += StrCopy(File, dest+i, sizeof(dest)-i); } if ((Self->ConfirmScript) AND (Self->Response != RSP_YESALL)) { if ((AnalyseLocation(dest, &type) IS ERR_Okay) AND ((type IS LOC_FILE) OR (type IS LOC_DIRECTORY))) { UserConfirmation(Self, Location, dest); } } if ((Self->Response != RSP_YES) AND (Self->Response != RSP_YESALL)) { DPrintF("FindFiles:","Skipping file %s, response %d", Location, Self->Response); return(ERR_Okay); } error = MoveLocation(Location, dest); if (error) { Self->Stop = TRUE; Self->Response = RSP_CANCEL; UserError(Self, Location, error); } return(ERR_Okay); } static void UserConfirmation(struct FindFiles *Self, STRING SrcFile, STRING DestFile) { OBJECTPTR script; if (Self->Response IS RSP_YESALL) return; if (!Self->ConfirmScript) { Self->Response = RSP_YES; return; } Self->Response = RSP_CANCEL; if (CreateObject(ID_SCRIPT, NF_CHILD, &script, NULL, FID_Location|TSTRING, Self->ConfirmScript, FID_SrcFile|TUNLISTED, SrcFile, FID_DestFile|TUNLISTED, DestFile, TAGEND) IS ERR_Okay) { acActivate(script); acFree(script); } } static void UserError(struct FindFiles *Self, STRING Location, ERROR ErrorCode) { OBJECTPTR script; if (!Self->ErrorScript) return; if (CreateObject(ID_SCRIPT, NF_CHILD, &script, NULL, FID_Location|TSTRING, Self->ErrorScript, FID_File|TUNLISTED, Location, TAGEND) IS ERR_Okay) { acActivate(script); acFree(script); } } I know that this is going to take up a bit of space and time but I mean if I can implement this easier the way I want to then so much the better. It would be easier for someone like yourself to use too, if you were to type "wget http://url/package" "gunzip package" "cd dir" "./configure" "make" "make clean" "make install" "package", compared to "search package install run" using natural language commands that you expect to be there. That's the hope anyway, but as you can see this just finds files on your local system, and doesn't do any of the stuff that I wanted it to, I did mainly lift it from gnu find but i've got another load of dirs under the same command dir 1 is for wget, 1 is for findfiles (the file I sent you), 1 is for nlp code so that find/search are accepted as the actual commands in bash instead of all of the above, etc etc so now I'm going to do it right and send that to gnu. Any docs you can point me in the direction of? __________________________________________________________________ Switch to Netscape Internet Service. As low as $9.95 a month -- Sign up today at http://isp.netscape.com/register Netscape. Just the Net You Need. New! Netscape Toolbar for Internet Explorer Search from anywhere on the Web and block those annoying pop-ups. Download now at http://channels.netscape.com/ns/search/install.jsp From grafik.list at redshift-software.com Wed Jul 6 05:04:15 2005 From: grafik.list at redshift-software.com (Rene Rivera) Date: Tue, 05 Jul 2005 22:04:15 -0500 Subject: [C++-sig] using libtool with boost.python In-Reply-To: References: Message-ID: <42CB4A2F.6010004@redshift-software.com> Dirgesh Patel wrote: > if i want to use libtool to compile and link all of my files in the JAMFILE > with boost.python...how can i do so, here is what my Jamfile looks like > currently. > > extension MaskUtil > : # sources > MaskUtil.cpp > > # requirements and dependencies for Boost.Python extensions >