From super24bitsound at hotmail.com Fri Jun 1 02:49:34 2012 From: super24bitsound at hotmail.com (Jay Riley) Date: Thu, 31 May 2012 20:49:34 -0400 Subject: [C++-sig] Properly copying wrapped classes In-Reply-To: <4FC51407.30098.2E1EA6CE@s_sourceforge.nedprod.com> References: <1338176220019-4630570.post@n4.nabble.com>, <4FC51407.30098.2E1EA6CE@s_sourceforge.nedprod.com> Message-ID: I'm having a problem with some python objects derived in python. I have a Clone method that's supposed to make a full copy of these python inherited objects, but it isn't working. The problem is my wrapper class' PyObject* self isn't getting copied, so when I use call_method<>(self, "method name"), self will never point to the copied instance. Here's a brief example showing the issue C++ file: #include #include using namespace boost::python; class BaseClass{public: typedef boost::shared_ptr ClonePtr; BaseClass() : ID(++IDCounter) { } BaseClass(const BaseClass& cp) : ID(++IDCounter) { } virtual boost::shared_ptr Clone() { return boost::shared_ptr(new BaseClass(*this)); } virtual int GetID() const { return ID; } virtual void Test() { std::cout << "C++ side ID: " << ID << "\n"; }protected: int ID;private: static int IDCounter;}; class BaseClassWrap : public BaseClass{public: BaseClassWrap(PyObject* self_) : self(self_) { } BaseClassWrap(PyObject* self_, const BaseClass& cp) : self(self_), BaseClass(cp) { } BaseClassWrap(PyObject* self_, const BaseClassWrap& cp) : self(self_), BaseClass(cp) { } virtual int GetID() const override { return call_method(self, "GetID"); } virtual void Test() { call_method(self, "Test"); } void TestDefault() { BaseClass::Test(); } int GetIDDefault() const { return BaseClass::GetID(); } boost::shared_ptr Clone() override { return call_method(self, "Clone"); } boost::shared_ptr CloneDefault() const { return boost::shared_ptr(new BaseClassWrap(*this)); } PyObject* self;private:}; BOOST_PYTHON_MODULE(TestModule){ class_ >("BaseClass", init<>()) .def(init()) .def(init()) .def("GetID", &BaseClassWrap::GetIDDefault) .def("Clone", &BaseClassWrap::CloneDefault) .def("Test", &BaseClassWrap::TestDefault) .def("__copy__", &generic__copy__< BaseClassWrap >) .def("__deepcopy__", &generic__deepcopy__< BaseClassWrap >) ;} int BaseClass::IDCounter = 0; int main(){ PyImport_AppendInittab("TestModule", initTestModule); Py_Initialize(); try { auto EngineModule = object( (handle<>(PyImport_ImportModule("TestModule"))) ); auto MainModule = object((handle<>(borrowed(PyImport_AddModule("__main__"))))); auto MainNamespace = MainModule.attr("__dict__"); MainNamespace["TestModule"] = EngineModule; object result = exec_file("D:\\FinalReport\\Test.py", MainNamespace, MainNamespace); object test = MainNamespace["test"]; boost::shared_ptr basec = extract >(test()); if (basec.get() != nullptr) { auto cl = basec->Clone(); basec->Test(); cl->Test(); std::cout << "Original ID " << basec->GetID() << "\n"; std::cout << "Clone ID " << cl->GetID() << "\n"; } } catch (boost::python::error_already_set) { PyErr_Print(); } return 0;} generic__copy__ and generic__deep__copy are in ScriptHelpers and shown below. They were pulled from an old thread on this mailing list and look like: #define PYTHON_ERROR(TYPE, REASON) \ { \ PyErr_SetString(TYPE, REASON); \ throw error_already_set(); \ } template inline PyObject * managingPyObject(T *p) { return typename manage_new_object::apply::type()(p); } template object generic__copy__(object copyable) { Copyable *newCopyable(new Copyable(extract(copyable))); object result(boost::python::detail::new_reference(managingPyObject(newCopyable))); extract(result.attr("__dict__"))().update( copyable.attr("__dict__")); return result; } template object generic__deepcopy__(object copyable, dict memo) { object copyMod = import("copy"); object deepcopy = copyMod.attr("deepcopy"); Copyable *newCopyable(new Copyable(extract(copyable))); object result(boost::python::detail::new_reference(managingPyObject(newCopyable))); // HACK: copyableId shall be the same as the result of id(copyable) //in Python - // please tell me that there is a better way! (and which ;-p) int copyableId = (int)(copyable.ptr()); memo[copyableId] = result; extract(result.attr("__dict__"))().update( deepcopy(extract(copyable.attr("__dict__"))(), memo)); return result; } and the python file: from TestModule import *import copy class Der(BaseClass): def Test(self): print "Python Side Test. ID: " + str(self.GetID()) def Clone(self): print "Python Clone" return copy.deepcopy(self) def test(): return Der() Sorry about the length, just want to make sure I got everything relevant in. When I run this code, it prints: Python Clone Python Side Test. ID: 1Python Side Test. ID: 1Original ID 1Clone ID 1 this is wrong because Clone ID should be 2 (inspecting the object confirms it is 2). Like I said I'm pretty sure the problem is that the wrapper class' copy constructor only makes a copy of the PyObject* self, not a full copy. This is how every reference doc I saw was doing class wrapping, but isn't this wrong? Should we be making a full copy of the PyObject*? How would I go about doing that, or otherwise modifying my classes to get the behaviour I expect. Thanks -------------- next part -------------- An HTML attachment was scrubbed... URL: From jbosch at astro.princeton.edu Sun Jun 3 17:25:38 2012 From: jbosch at astro.princeton.edu (Jim Bosch) Date: Sun, 03 Jun 2012 11:25:38 -0400 Subject: [C++-sig] Properly copying wrapped classes In-Reply-To: References: <1338176220019-4630570.post@n4.nabble.com>, <4FC51407.30098.2E1EA6CE@s_sourceforge.nedprod.com> Message-ID: <4FCB81F2.1000000@astro.princeton.edu> On 05/31/2012 08:49 PM, Jay Riley wrote: > I'm having a problem with some python objects derived in python. I have > a Clone method that's supposed to make a full copy of these python > inherited objects, but it isn't working. The problem is my wrapper > class' PyObject* self isn't getting copied, so when I use > call_method<>(self, "method name"), self will never point to the copied > instance. Here's a brief example showing the issue > > > Sorry about the length, just want to make sure I got everything relevant > in. When I run this code, it prints: > > Python Clone > Python Side Test. ID: 1 > Python Side Test. ID: 1 > Original ID 1 > Clone ID 1 > > this is wrong because Clone ID should be 2 (inspecting the object > confirms it is 2). Like I said I'm pretty sure the problem is that the > wrapper class' copy constructor only makes a copy of the PyObject* self, > not a full copy. This is how every reference doc I saw was doing class > wrapping, but isn't this wrong? Should we be making a full copy of the > PyObject*? How would I go about doing that, or otherwise modifying my > classes to get the behaviour I expect. > There are a couple of things here that probably need to be addressed: - Be wary of relying on copy-constructor side effects to demonstrate whether something is working; the compiler is allowed to elide copy constructors under many conditions, which might result in misleading results. That said, I don't think that's what's causing your problem here (or at least not all of it). - Your implementations of __copy__ and __deepcopy__ won't work with polymorphic wrapper classes, because they construct a BaseClass instance and tell Boost.Python to wrap it by managing the new reference. That necessarily makes a Python object that holds a BaseClass object, not one that holds a BaseClassWrap object. If you want to get a BaseClassWrap Python object, you want to pass it by value to Boost.Python; that should invoke the BaseClassWrap copy constructor and pass it a new PyObject* to manage (so it doesn't have to copy the PyObject* itself). I think that just means you can remove the "managingPyObject" function, and instead use: object result(extract(copyable)()); HTH Jim From srirangamnagaraju at gmail.com Wed Jun 6 11:09:00 2012 From: srirangamnagaraju at gmail.com (Nagaraju) Date: Wed, 6 Jun 2012 14:39:00 +0530 Subject: [C++-sig] Accessing Class Member Function from Python Message-ID: Hi, I have written a sample DLL in C++. It has a class and functions for add, sub, mul and div. I wrote a wrapper class in the same file as BOOST_PYTHON_MODULE(hello). Now when I compiled this DLL, I get Test.DLL. Now from Python, I wrote a script to load this Test.DLL. How can I access add, sub and other functions in my Python script? Request anybody to help me on this. Regards, Raju. -------------- next part -------------- An HTML attachment was scrubbed... URL: From nat at lindenlab.com Wed Jun 6 12:50:36 2012 From: nat at lindenlab.com (Nat Linden) Date: Wed, 6 Jun 2012 06:50:36 -0400 Subject: [C++-sig] Accessing Class Member Function from Python In-Reply-To: References: Message-ID: On Wed, Jun 6, 2012 at 5:09 AM, Nagaraju wrote: > I wrote a wrapper class in the same file as BOOST_PYTHON_MODULE(hello). > > Now when I compiled this DLL, I get Test.DLL. Hmm, the module thinks its name is "hello", but it's in Test.DLL? Maybe it should be hello.pyd? The .pyd is to designate it as a Python extension. Python stopped importing plain .dlls along about Python 2.5. > Now from Python, I wrote a script to load this Test.DLL. As 'import Test' or as 'import hello'? > How can I access add, sub and other functions in my Python script? You said you wrote a wrapper class, and that the add, sub etc. are methods on that class? Let's say your wrapper class is called Wrapper. import hello obj = hello.Wrapper() # instantiate -- or, equivalently -- from hello import Wrapper obj = Wrapper() -- then, either way -- print obj.add(something, something_else) From srirangamnagaraju at gmail.com Wed Jun 6 12:57:18 2012 From: srirangamnagaraju at gmail.com (Nagaraju) Date: Wed, 6 Jun 2012 16:27:18 +0530 Subject: [C++-sig] Accessing Class Member Function from Python In-Reply-To: References: Message-ID: Hi Nat, Thank you very much for your reply. I am sorry if I did not explain something clearly. The output file I am generating is as Test.DLL only. I am not generating it as .pyd. This DLL has a class called MyClass. In it, I have add, sub, mul n div. I am doing as below after implementing the MyClass in the same file: BOOST_PYTHON_MODULE(hello){ class_("MyClass") .def("add",&MyClass::add); } I am using CDLL from ctypes to load this Test.DLL. Say planet = CDLL("Test.DLL"). Now I want to create an object of MyClass and call add function. How can I do this? Regards, Raju. On Wed, Jun 6, 2012 at 4:20 PM, Nat Linden wrote: > On Wed, Jun 6, 2012 at 5:09 AM, Nagaraju > wrote: > > > I wrote a wrapper class in the same file as BOOST_PYTHON_MODULE(hello). > > > > Now when I compiled this DLL, I get Test.DLL. > > Hmm, the module thinks its name is "hello", but it's in Test.DLL? > Maybe it should be hello.pyd? > > The .pyd is to designate it as a Python extension. Python stopped > importing plain .dlls along about Python 2.5. > > > Now from Python, I wrote a script to load this Test.DLL. > > As 'import Test' or as 'import hello'? > > > How can I access add, sub and other functions in my Python script? > > You said you wrote a wrapper class, and that the add, sub etc. are > methods on that class? > > Let's say your wrapper class is called Wrapper. > > import hello > obj = hello.Wrapper() # instantiate > > -- or, equivalently -- > > from hello import Wrapper > obj = Wrapper() > > -- then, either way -- > > print obj.add(something, something_else) > _______________________________________________ > Cplusplus-sig mailing list > Cplusplus-sig at python.org > http://mail.python.org/mailman/listinfo/cplusplus-sig > -------------- next part -------------- An HTML attachment was scrubbed... URL: From nat at lindenlab.com Wed Jun 6 15:27:46 2012 From: nat at lindenlab.com (Nat Linden) Date: Wed, 6 Jun 2012 09:27:46 -0400 Subject: [C++-sig] Accessing Class Member Function from Python In-Reply-To: References: Message-ID: On Wed, Jun 6, 2012 at 6:57 AM, Nagaraju wrote: > Thank you very much for your reply. I am sorry if I did not explain > something clearly. > > I am doing as below after implementing the MyClass in the same file: > > BOOST_PYTHON_MODULE(hello){ > ... > } > > I am using CDLL from ctypes to load this Test.DLL. Say > planet = CDLL("Test.DLL"). > > Now I want to create an object of MyClass and call add function. How can I > do this? I think you're mixing two different tactics here. You can use ctypes to load a plain DLL that publishes extern "C" functions, and call those functions. But I don't believe it supports the notion of a Python class defined in that DLL. Or you can use Boost.Python to prepare a special DLL that Python will recognize as an extension module. Such modules can be loaded with 'import'. In this case you don't use ctypes because the module contents describe themselves for the Python runtime to know how to use them directly, classes and methods and functions and data. Boost.Python is a succinct way to provide such a description. But it's my belief that a DLL containing the description compiled from BOOST_PYTHON_MODULE(hello) must be named "hello.pyd" for the Python interpreter to successfully import it. Once you're able to import hello, you should be able to instantiate hello.MyClass() and proceed from there. From srirangamnagaraju at gmail.com Wed Jun 6 15:38:50 2012 From: srirangamnagaraju at gmail.com (Nagaraju) Date: Wed, 6 Jun 2012 19:08:50 +0530 Subject: [C++-sig] Accessing Class Member Function from Python In-Reply-To: References: Message-ID: Hi Nat, Thank you very much for the reply. I tried making the target as ".pyd" and I am able to import it in Python script. Thanks again. Regards, Raju. On Wed, Jun 6, 2012 at 6:57 PM, Nat Linden wrote: > On Wed, Jun 6, 2012 at 6:57 AM, Nagaraju > wrote: > > > Thank you very much for your reply. I am sorry if I did not explain > > something clearly. > > > > I am doing as below after implementing the MyClass in the same file: > > > > BOOST_PYTHON_MODULE(hello){ > > ... > > } > > > > I am using CDLL from ctypes to load this Test.DLL. Say > > planet = CDLL("Test.DLL"). > > > > Now I want to create an object of MyClass and call add function. How can > I > > do this? > > I think you're mixing two different tactics here. > > You can use ctypes to load a plain DLL that publishes extern "C" > functions, and call those functions. But I don't believe it supports > the notion of a Python class defined in that DLL. > > Or you can use Boost.Python to prepare a special DLL that Python will > recognize as an extension module. Such modules can be loaded with > 'import'. In this case you don't use ctypes because the module > contents describe themselves for the Python runtime to know how to use > them directly, classes and methods and functions and data. > Boost.Python is a succinct way to provide such a description. > > But it's my belief that a DLL containing the description compiled from > BOOST_PYTHON_MODULE(hello) must be named "hello.pyd" for the Python > interpreter to successfully import it. > > Once you're able to import hello, you should be able to instantiate > hello.MyClass() and proceed from there. > _______________________________________________ > Cplusplus-sig mailing list > Cplusplus-sig at python.org > http://mail.python.org/mailman/listinfo/cplusplus-sig > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jjchristophe at yahoo.fr Fri Jun 8 11:49:10 2012 From: jjchristophe at yahoo.fr (christophe jean-joseph) Date: Fri, 8 Jun 2012 10:49:10 +0100 (BST) Subject: [C++-sig] changing argument value in a C++/Python code In-Reply-To: References: Message-ID: <1339148950.54266.YahooMailNeo@web132305.mail.ird.yahoo.com> My problem is as follow: I have a C++ code that I can't modify as I want (not written by me and under some intellectual property constraints). I have to link it with a Python code through a Python main. I use boost::python for the reflection. At some point in the code, a C++ function use a Python overloaded function of a C++ function to modify a parameter. This function works great when used inside Python. But when called by a C++ function, the modification of the parameter will not be taken into account while back in C++. To model the problem, I wrote a simplified version aimed at isolating my problem. Here are the C++ classes: #include using namespace std; #include class A { public: A(){int A_x=0;} virtual ~A(){} virtual int f(int Ivar){ Ivar = 0; return Ivar; } virtual void g(double Dvar){ Dvar = 0.; } double h(){ double Dvar; Dvar = 0.; this->g(Dvar); cout << Dvar << endl; Dvar = Dvar*2; return Dvar; } }; class B { public: B(A & a){ setparam(a);? } B(){ int u; u = 0; } virtual ~B(){} void setparam(A & a){ a.h();? } }; The boost python wrapper: #include #include #include #include "ClassA.h" //#include #include #include #include #include #include using namespace std; #include using namespace boost::python; struct WrapperClassA : A, boost::python::wrapper{ int f(int Ivar){ if(override f = this->get_override("f")){ return f(Ivar); } else { return A::f(Ivar); } } int default_f(int Ivar){ return this->A::f(Ivar); } void g(double Dvar){ if(override g = this->get_override("g")){ g(Dvar); } else { A::g(Dvar); } } void default_g(double Dvar){ this->A::g(Dvar); } }; BOOST_PYTHON_MODULE(myWrapper){ class_("A", init<>()) .def("f", &A::f, &WrapperClassA::default_f) .def("g", &A::g, &WrapperClassA::default_g) ; class_("B", init<>()) .def("setparam", &B::setparam) ; } The Python code: from math import * import random # Our Ilab library from myWrapper import * # Allow option choices. import argparse class APy(A): def __init__(self): A.__init__(self) n = 0 x = 0. def f(self, n): n = 5 return n def g(self, x): x = 7.0 print("value in Python: " + repr(x)) myA = APy() myB = B() myB.setparam(myA) When I run the code,?print("value in Python: " + repr(x)) print 7, but?cout << Dvar << endl print 0 while I would like the variable to be at 7. Thank you for any help. CHRISTOPHE Jean-Joseph -------------- next part -------------- An HTML attachment was scrubbed... URL: From jjchristophe at yahoo.fr Fri Jun 8 14:46:13 2012 From: jjchristophe at yahoo.fr (christophe jean-joseph) Date: Fri, 8 Jun 2012 13:46:13 +0100 (BST) Subject: [C++-sig] Re : changing argument value in a C++/Python code In-Reply-To: <1339148950.54266.YahooMailNeo@web132305.mail.ird.yahoo.com> References: <1339148950.54266.YahooMailNeo@web132305.mail.ird.yahoo.com> Message-ID: <1339159573.12439.YahooMailNeo@web132303.mail.ird.yahoo.com> As my code was uncommented and uncomplete, I post it again with necessary corrections. C++ classes: #include using namespace std; /* Class aimed at modeling a C++ user's type that should be used in Python */ class C { public: double myC; C(){} ~C(){} void setValue(double val) { myC = val; ? ? } ? ? double getValue() { return myC; ? ? } }; /* This class will be derived in Python We want to be sure that: - void (g) and non void (f) functions are properly reflected and extended in Python - a function (h) with a local type (C) will properly use the python overloaded function of a C++ function (g) */ class A { public: A(){int A_x=0;} virtual ~A(){} virtual int f(int Ivar){ Ivar = 0; return Ivar; } virtual void g(C * myC){ C calledC; cout << "I should not be here" << endl; ? //When B::setparam call g, it should be the Python g, not the virtual function from base class calledC.setValue(0.); } C h(){//This function wont be overloaded in Python C myC; this->g(&myC);//We want myC to be modified, and the python overloaded version of g to be used C calledC; double myCint; myCint = calledC.getValue(); cout << "Value back in C++: " << myCint << endl; //We want to verify if myC has been modified back in C++ myCint = myCint*2; calledC.setValue(myCint); return myC; } }; /* This class will be called from a main in Python. It's function setparam is aimed at ensuring that Python extension of a C++ class is supported properly */ class B { public: B(A & a){ setparam(a);? } B(){ int u; u = 0; } virtual ~B(){} void setparam(A & a){ a.h();//Here the code should call the h overloaded function of the derived class of A in Python } }; Boost::Python Wrapper: #include #include #include #include "ClassA.h" #include #include #include #include using namespace std; using namespace boost::python; /* A wrapper is used to allow overload of virtual A function */ struct WrapperClassA : A, boost::python::wrapper{ int f(int Ivar){ if(override f = this->get_override("f")){ return f(Ivar); } else { return A::f(Ivar); } } int default_f(int Ivar){ return this->A::f(Ivar); } void g(C * myC){ if(override g = this->get_override("g")){ g(myC); } else { A::g(myC); } } void default_g(C * myC){ this->A::g(myC); } }; /* Refection of necessary classes and functions for Python */ BOOST_PYTHON_MODULE(myWrapper){ class_("A", init<>()) .def("f", &A::f, &WrapperClassA::default_f) .def("g", &A::g, &WrapperClassA::default_g) ; class_("B", init<>()) .def("setparam", &B::setparam) ; ? ? class_("C", init<>()) ? ? .def("setValue", &C::setValue) ? ? .def("getValue", &C::getValue) ? ? .def_readwrite("myC", &C::myC) ? ? ; } Python code: from math import * # C++ library from myWrapper import * """ Extension of C++ class A APy be used when A type argument is called g should be able to use a C++ C type object and to modify it """ class APy(A): def __init__(self): A.__init__(self) n = 0 x = 0. def f(self, n): n = 5 return n def g(self, myC): calledC = C() x = 7.0 calledC.setValue(x) print("value in Python: " + repr(calledC.getValue())) """ Main myB.setparam should be able to pass a APy argument """ myA = APy() myB = B() myB.setparam(myA) When I run the code,?print("value in Python: " + repr(calledC.getValue()))??print 7, but?cout << "Value back in C++: " << myCint << endl?print -9.25596e+061 while I would like the variable to be at 7. Thank you for any help. CHRISTOPHE Jean-Joseph -------------- next part -------------- An HTML attachment was scrubbed... URL: From sybren at stuvel.eu Fri Jun 8 14:48:26 2012 From: sybren at stuvel.eu (=?UTF-8?Q?Sybren_A=2E_St=C3=BCvel?=) Date: Fri, 8 Jun 2012 14:48:26 +0200 Subject: [C++-sig] Boost::Python: overriding and smart pointers In-Reply-To: References: Message-ID: Dear List, Can anyone give me a hand in solving this? Kind regards, Sybren On 23 May 2012 16:21, Sybren A. St?vel wrote: > Dear list, > > I'm trying to get my head around shared pointers combined with overloaded > methods. I want to create instances of my class both in Python and C++, but > for some reason I can't get both to work with the same code. I've > constructed a minimal example to show you what I'm trying to do. The full > C++ code with syntax highlighting can be found at > http://pastebin.com/ZqG79QUL > > Sorry for the long mail, but I saw no other way to show my issues in a > clear and unambiguous way. > > -------------------------------------- > class ExampleObject { > public: > std::string name; > > ExampleObject(const std::string & name) : name(name) {} > virtual ~ExampleObject() {} > virtual int some_number() { return 12; } > }; > > typedef boost::shared_ptr ExampleObjectPtr; > > ExampleObjectPtr create_example_object(const std::string & name) { > return boost::make_shared(name); > } > > void print_name(ExampleObjectPtr object) { > std::cout << "Example object named '" << object->name > << "', nr = " << object->some_number() > << std::endl; > } > -------------------------------------- > > These are the class and functions that I want to wrap. The > ExampleObject::some_number method should be overridable in Python. To this > end, I've created the following wrapper class: > > -------------------------------------- > struct ExampleObject_wrapper : ExampleObject, wrapper { > ExampleObject_wrapper(const std::string & name) > : ExampleObject(name), wrapper() > {} > > virtual int some_number(void) override { > if( override func_override = this->get_override("some_number")) > return func_override(); > return default_some_number(); > } > > int default_some_number(void) { > return this->ExampleObject::some_number(); > } > }; > > typedef boost::shared_ptr ExampleObject_wrapper_ptr; > -------------------------------------- > > The Python module is declared as follows: > > -------------------------------------- > BOOST_PYTHON_MODULE(wraptest) { > def("create_example_object", &create_example_object); > def("print_name", &print_name); > > class_ > ("ExampleObject", init()) > .def("some_number", &ExampleObject_wrapper::some_number, > &ExampleObject_wrapper::default_some_number) > ; > } > -------------------------------------- > > This is the Python code that I'm testing with: > > -------------------------------------- > from wraptest import * > > class ExampleSubclass(ExampleObject): > def some_number(self): > return ExampleObject.some_number(self) * 2 > > # Test from Python > from_py_obj = ExampleSubclass('from python') > print_name(from_py_obj) > > # Test from C++ > from_cpp = create_example_object('from C++') > print_name(from_cpp) > -------------------------------------- > > When I compile the module (VS2010, Python 3.2.2, Boost 1.48) and run the > Python script, I would expect the object created in C++ to show the number > 12, and the object created in Python to show the number 24. However, the > output is this: > > Example object named 'from python', nr = 12 > Example object named 'from C++', nr = 12 > > Running a debugger also shows that the ExampleObject_wrapper methods > aren't called at all. When I edit the class_<...> line by replacing > ExampleObjectPtr with ExampleObject_wrapper_ptr, the from-Python object > works just fine, but the from-C++ object gives me an exception: > > Example object named 'from python', nr = 24 > Traceback (most recent call last): > File "C:\workspace\rage\scripts\test_wrapping.py", line 13, in > from_cpp = create_example_object('from C++') > TypeError: No to_python (by-value) converter found for C++ type: class > boost::shared_ptr > > What should I do to be able to instantiate objects in C++ and Python alike? > > Kind regards, > -- > Sybren A. St?vel > > http://stuvel.eu/ > > > -- Sybren A. St?vel http://stuvel.eu/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From nat at lindenlab.com Fri Jun 8 17:14:43 2012 From: nat at lindenlab.com (Nat Linden) Date: Fri, 8 Jun 2012 11:14:43 -0400 Subject: [C++-sig] Re : changing argument value in a C++/Python code In-Reply-To: <1339159573.12439.YahooMailNeo@web132303.mail.ird.yahoo.com> References: <1339148950.54266.YahooMailNeo@web132305.mail.ird.yahoo.com> <1339159573.12439.YahooMailNeo@web132303.mail.ird.yahoo.com> Message-ID: On Fri, Jun 8, 2012 at 8:46 AM, christophe jean-joseph wrote: > class C > { > public: > double myC; > C(){} > ~C(){} > > void setValue(double val) { > myC = val; > ? ? } > > ? ? double getValue() { > return myC; > ? ? } > }; > ... > > class A > { > public: > ... > C h(){ //This function wont be overloaded in Python > C myC; > this->g(&myC); //We want myC to be modified, and the python overloaded > version of g to be used > C calledC; > double myCint; > myCint = calledC.getValue(); > cout << "Value back in C++: " << myCint << endl; //We want to verify if myC > has been modified back in C++ > myCint = myCint*2; > calledC.setValue(myCint); > return myC; > } > }; > > When I run the code,? ... > cout << "Value back in C++: " << > myCint << endl?print -9.25596e+061 while I would like the variable to be at > 7. At risk of sounding foolish, your output looks reasonable to me. In A::h(), at the point when you execute that cout << etc., this is all the data that seems to participate: > C calledC; > double myCint; > myCint = calledC.getValue(); > cout << "Value back in C++: " << myCint << endl; You instantiate a brand-new 'C' object calledC. Its constructor doesn't initialize C::myC, therefore it's uninitialized. You then call calledC.getValue(), which returns that uninitialized double. myCint is therefore a strange-looking value. From jjchristophe at yahoo.fr Fri Jun 8 17:51:48 2012 From: jjchristophe at yahoo.fr (christophe jean-joseph) Date: Fri, 8 Jun 2012 16:51:48 +0100 (BST) Subject: [C++-sig] Re : Re : changing argument value in a C++/Python code In-Reply-To: References: <1339148950.54266.YahooMailNeo@web132305.mail.ird.yahoo.com> <1339159573.12439.YahooMailNeo@web132303.mail.ird.yahoo.com> Message-ID: <1339170708.93593.YahooMailNeo@web132306.mail.ird.yahoo.com> Thank you very much for your answer. I may add two things: 1.? I modified the Python derived class in order to be sure that myC is treated as mutable within Python class APy(A): def __init__(self): A.__init__(self) n = 0 x = 0. myC = C() self.g(myC) print("value after a 1st call within Python: " + repr(myC.getValue())) def f(self, n): n = 5 return n def g(self, myC): x = 7.0 myC.setValue(x) print("value in Python: " + repr(myC.getValue())) As a result, myC is modified in the constructor's call (print("value after a 1st call within Python: " + repr(myC.getValue())) send 7 as expected). Thus, myC is clearly treated as mutable (I wasn't sure about it). 2. As I said, I can't modify the original C++ code as I would like. In the original code, instead of a double, the "C" object is originaly a vector, and I verify the size of the vector. The original code look like this: C CVector; this->dosomething(&CVector) and, though CVector is modified within dosomething (which is a C++ function originaly, but I have to use the python overloaded version that I wrote), it will lose the modification while using the python overloaded function. As my function h was clumsy written, I modified it as well: C h(){//This function wont be overloaded in Python C myC; this->g(&myC);//We want myC to be modified, and the python overloaded version of g to be used cout << "Value back in C++: " << myC.getValue() << endl; //We want to verify if myC has been modified back in C++ return myC; } when g is called by h, myC is modified inside APy.g, but back to C++ I still have the strange-looking value. Isn't C myC the initialisation of myC? As it work fine for the full C++ code, and as the argument is treated as mutable within Python, I don't really understand what's wrong. Moreover, I should avoid to modify the original C++ code as much as possible. Jean-Joseph ________________________________ De?: Nat Linden ??: Development of Python/C++ integration Envoy? le : Vendredi 8 juin 2012 17h14 Objet?: Re: [C++-sig] Re : changing argument value in a C++/Python code On Fri, Jun 8, 2012 at 8:46 AM, christophe jean-joseph wrote: > class C > { > public: > double myC; > C(){} > ~C(){} > > void setValue(double val) { > myC = val; > ? ? } > > ? ? double getValue() { > return myC; > ? ? } > }; > ... > > class A > { > public: > ... > C h(){ //This function wont be overloaded in Python > C myC; > this->g(&myC); //We want myC to be modified, and the python overloaded > version of g to be used > C calledC; > double myCint; > myCint = calledC.getValue(); > cout << "Value back in C++: " << myCint << endl; //We want to verify if myC > has been modified back in C++ > myCint = myCint*2; > calledC.setValue(myCint); > return myC; > } > }; > > When I run the code,? ... > cout << "Value back in C++: " << > myCint << endl?print -9.25596e+061 while I would like the variable to be at > 7. At risk of sounding foolish, your output looks reasonable to me. In A::h(), at the point when you execute that cout << etc., this is all the data that seems to participate: > C calledC; > double myCint; > myCint = calledC.getValue(); > cout << "Value back in C++: " << myCint << endl; You instantiate a brand-new 'C' object calledC. Its constructor doesn't initialize C::myC, therefore it's uninitialized. You then call calledC.getValue(), which returns that uninitialized double. myCint is therefore a strange-looking value. _______________________________________________ Cplusplus-sig mailing list Cplusplus-sig at python.org http://mail.python.org/mailman/listinfo/cplusplus-sig -------------- next part -------------- An HTML attachment was scrubbed... URL: From jjchristophe at yahoo.fr Fri Jun 8 17:59:44 2012 From: jjchristophe at yahoo.fr (christophe jean-joseph) Date: Fri, 8 Jun 2012 16:59:44 +0100 (BST) Subject: [C++-sig] Re : Re : changing argument value in a C++/Python code, about initialisation In-Reply-To: References: <1339148950.54266.YahooMailNeo@web132305.mail.ird.yahoo.com> <1339159573.12439.YahooMailNeo@web132303.mail.ird.yahoo.com> Message-ID: <1339171184.98042.YahooMailNeo@web132301.mail.ird.yahoo.com> I changed the first line of A::h to C myC; myC.setValue(0.); this->g(&myC); I don't know if it match your comment, but the result is myC read at 0 instead of a strange-value, which is still not 7. CHRISTOPHE Jean-Joseph ________________________________ De?: Nat Linden ??: Development of Python/C++ integration Envoy? le : Vendredi 8 juin 2012 17h14 Objet?: Re: [C++-sig] Re : changing argument value in a C++/Python code On Fri, Jun 8, 2012 at 8:46 AM, christophe jean-joseph wrote: > class C > { > public: > double myC; > C(){} > ~C(){} > > void setValue(double val) { > myC = val; > ? ? } > > ? ? double getValue() { > return myC; > ? ? } > }; > ... > > class A > { > public: > ... > C h(){ //This function wont be overloaded in Python > C myC; > this->g(&myC); //We want myC to be modified, and the python overloaded > version of g to be used > C calledC; > double myCint; > myCint = calledC.getValue(); > cout << "Value back in C++: " << myCint << endl; //We want to verify if myC > has been modified back in C++ > myCint = myCint*2; > calledC.setValue(myCint); > return myC; > } > }; > > When I run the code,? ... > cout << "Value back in C++: " << > myCint << endl?print -9.25596e+061 while I would like the variable to be at > 7. At risk of sounding foolish, your output looks reasonable to me. In A::h(), at the point when you execute that cout << etc., this is all the data that seems to participate: > C calledC; > double myCint; > myCint = calledC.getValue(); > cout << "Value back in C++: " << myCint << endl; You instantiate a brand-new 'C' object calledC. Its constructor doesn't initialize C::myC, therefore it's uninitialized. You then call calledC.getValue(), which returns that uninitialized double. myCint is therefore a strange-looking value. _______________________________________________ Cplusplus-sig mailing list Cplusplus-sig at python.org http://mail.python.org/mailman/listinfo/cplusplus-sig -------------- next part -------------- An HTML attachment was scrubbed... URL: From stefan at seefeld.name Fri Jun 8 18:16:18 2012 From: stefan at seefeld.name (Stefan Seefeld) Date: Fri, 08 Jun 2012 12:16:18 -0400 Subject: [C++-sig] Re : changing argument value in a C++/Python code In-Reply-To: <1339159573.12439.YahooMailNeo@web132303.mail.ird.yahoo.com> References: <1339148950.54266.YahooMailNeo@web132305.mail.ird.yahoo.com> <1339159573.12439.YahooMailNeo@web132303.mail.ird.yahoo.com> Message-ID: <4FD22552.6090006@seefeld.name> Christoph, your C++ code passes a pointer argument to the "g()" member function, but your Python bindings don't specify a call policy. (I wonder why that doesn't raise a compilation error.) The effect mostly likely is that in fact the value is copied, so you see a new object. Explicit is better than implicit. Stefan -- ...ich hab' noch einen Koffer in Berlin... From super24bitsound at hotmail.com Sat Jun 9 02:40:07 2012 From: super24bitsound at hotmail.com (Jay Riley) Date: Fri, 8 Jun 2012 20:40:07 -0400 Subject: [C++-sig] Properly copying wrapped classes In-Reply-To: <4FD11993.1040406@astro.princeton.edu> References: <1338176220019-4630570.post@n4.nabble.com>, <4FC51407.30098.2E1EA6CE@s_sourceforge.nedprod.com> , <4FCB81F2.1000000@astro.princeton.edu> , <4FCCD9CA.9010400@astro.princeton.edu> , <4FD11993.1040406@astro.princeton.edu> Message-ID: I replaced my template copy with object bc_copy(object copyable, dict memo){ object copyMod = import("copy"); object deepcopy = copyMod.attr("deepcopy"); BaseClassWrap *newCopyable(new BaseClassWrap(extract(copyable))); BaseClass tmp = boost::python::extract(copyable); object result(tmp); int copyableId = (int)(copyable.ptr()); memo[copyableId] = result; extract(result.attr("__dict__"))().update( deepcopy(extract(copyable.attr("__dict__"))(), memo)); return result;} and wrapped class_ >("BaseClass", init<>()) .def(init()) .def(init()) .def("GetID", &BaseClassWrap::GetIDDefault) .def("Clone", &BaseClassWrap::CloneDefault) .def("Test", &BaseClassWrap::TestDefault) .def("__copy__", &generic__copy__< BaseClass >) .def("__deepcopy__", &bc_copy) ; But I'm still getting the non overriden behaviour. Calling Test on the clone prints out the C++ side code, while the non clone prints out the python side code. > Date: Thu, 7 Jun 2012 17:13:55 -0400 > From: jbosch at astro.princeton.edu > To: super24bitsound at hotmail.com > Subject: Re: [C++-sig] Properly copying wrapped classes > > On 06/05/2012 12:41 AM, Jay Riley wrote: > > That got rid of the compile time errors. However, On the python side I > > get the following error when I try to clone: > > > > > > File ... line 9 in Clone > > return copy.deepcopy(self) > > File C:\Python27\Lib\copy.py" line 174 in deepcopy > > y = copier(memo) > > TypeError: No to_python (by-value) converter for C++ type: class > > BaseClassWrap > > > > Hmm. I would have expected that to work. As long as BaseClass can be > instantiated itself (i.e. it isn't pure abstract), you could try this in > the copy/deepcopy implementation: > > BaseClass tmp = boost::python::extract(copyable); > object result(tmp); > > (I don't remember which of these types your Copyable template parameter > was, but I'd recommend just trying to write this in a non-template > function until you get it working). > > That will involve one extra copy, but it should invoke the BaseClass > by-value converter instead of the BaseClassWrap by-value converter, and > I *think* that should do the right thing. > > > Jim > > > > > > In the interest of trying it out, I added the BaseClassWrap to the > > python module > > > > class_ >("BaseClassWrap", init()) > > .def(init()) > > .def(init()) > > .def("__copy__", &generic__copy__< BaseClassWrap >) > > .def("__deepcopy__", &generic__deepcopy__< BaseClassWrap >) > > ; > > > > But this put me back at square one, where self isn't indicative of the > > cloned instance. > > > > Just in the interest of seeing the effect, I changed my python exposing to: > > > > class_ >("BaseClass", init<>()) > > .def(init()) > > .def(init()) > > .def("GetID", &BaseClassWrap::GetIDDefault) > > .def("Clone", &BaseClassWrap::CloneDefault) > > .def("Test", &BaseClassWrap::TestDefault) > > .def("__copy__", &generic__copy__< BaseClass >) > > .def("__deepcopy__", &generic__deepcopy__< BaseClass >) > > ; > > > > But as expected, the overloading doesn't work on clones made with this > > exposing. Anything else I should try? > > > > Again, thanks for the help so far, appreciate it. > > > > > > > > > > > Date: Mon, 4 Jun 2012 11:52:42 -0400 > > > From: jbosch at astro.princeton.edu > > > To: super24bitsound at hotmail.com > > > Subject: Re: [C++-sig] Properly copying wrapped classes > > > > > > On 06/04/2012 12:58 AM, Jay Riley wrote: > > > > > > > > Hi Jim, > > > > Thanks for the help so far. From what you said, I should be able to > > change my deepcopy to this correct? > > > > > > > > template object generic__deepcopy__(object > > copyable, dict memo) { object copyMod = import("copy"); object deepcopy > > = copyMod.attr("deepcopy"); > > > > Copyable *newCopyable(new Copyable(extract > &>(copyable))); //object > > result(boost::python::detail::new_reference(managingPyObject(newCopyable))); > > > > object result(extract(copyable)()); > > > > // HACK: copyableId shall be the same as the result of id(copyable) > > //in Python - // please tell me that there is a better way! (and which > > ;-p) int copyableId = (int)(copyable.ptr()); memo[copyableId] = result; > > > > extract(result.attr("__dict__"))().update( > > deepcopy(extract(copyable.attr("__dict__"))(), memo)); > > > > return result; } > > > > When I attempt to compile it gives me the following error: > > > > Error 48 error C2664: 'boost::python::api::object::object(const > > boost::python::api::object&)' : cannot convert parameter 1 from > > 'boost::python::api::object (__cdecl *)(boost::python::extract > > (__cdecl *)(void))' to 'const boost::python::api::object&' > > c:\khmp\src\engine\scripting\python\scripthelpers.h 67 > > > > Did you mean something else? This level of boost python is above my > > head, so I'm a bit lost > > > > > > > > > > It looks like the version I gave you is a bad corner case where the > > > compiler is incapable of parsing a constructor properly when templates > > > and overloaded function-call operators are involved; I always forget > > > exactly when that comes into play (not a compiler bug, just a weird part > > > of the standard, I think). In any case, I think separating it into two > > > lines should fix the problem: > > > > > > const Copyable & tmp = extract(copyable); > > > object result(tmp); > > > > > > Let me know if that doesn't work either; at that point I should try to > > > compile it myself and see what's going on. > > > > > > Jim > > > > > > > > > > > > > > > > > > >> Date: Sun, 3 Jun 2012 11:25:38 -0400 > > > >> From: jbosch at astro.princeton.edu > > > >> To: cplusplus-sig at python.org > > > >> CC: super24bitsound at hotmail.com > > > >> Subject: Re: [C++-sig] Properly copying wrapped classes > > > >> > > > >> On 05/31/2012 08:49 PM, Jay Riley wrote: > > > >>> I'm having a problem with some python objects derived in python. > > I have > > > >>> a Clone method that's supposed to make a full copy of these python > > > >>> inherited objects, but it isn't working. The problem is my wrapper > > > >>> class' PyObject* self isn't getting copied, so when I use > > > >>> call_method<>(self, "method name"), self will never point to the > > copied > > > >>> instance. Here's a brief example showing the issue > > > >>> > > > >> > > > >> > > > >> > > > >>> > > > >>> Sorry about the length, just want to make sure I got everything > > relevant > > > >>> in. When I run this code, it prints: > > > >>> > > > >>> Python Clone > > > >>> Python Side Test. ID: 1 > > > >>> Python Side Test. ID: 1 > > > >>> Original ID 1 > > > >>> Clone ID 1 > > > >>> > > > >>> this is wrong because Clone ID should be 2 (inspecting the object > > > >>> confirms it is 2). Like I said I'm pretty sure the problem is > > that the > > > >>> wrapper class' copy constructor only makes a copy of the > > PyObject* self, > > > >>> not a full copy. This is how every reference doc I saw was doing > > class > > > >>> wrapping, but isn't this wrong? Should we be making a full copy > > of the > > > >>> PyObject*? How would I go about doing that, or otherwise modifying my > > > >>> classes to get the behaviour I expect. > > > >>> > > > >> > > > >> There are a couple of things here that probably need to be addressed: > > > >> > > > >> - Be wary of relying on copy-constructor side effects to demonstrate > > > >> whether something is working; the compiler is allowed to elide copy > > > >> constructors under many conditions, which might result in misleading > > > >> results. That said, I don't think that's what's causing your problem > > > >> here (or at least not all of it). > > > >> > > > >> - Your implementations of __copy__ and __deepcopy__ won't work with > > > >> polymorphic wrapper classes, because they construct a BaseClass > > instance > > > >> and tell Boost.Python to wrap it by managing the new reference. That > > > >> necessarily makes a Python object that holds a BaseClass object, > > not one > > > >> that holds a BaseClassWrap object. If you want to get a BaseClassWrap > > > >> Python object, you want to pass it by value to Boost.Python; that > > should > > > >> invoke the BaseClassWrap copy constructor and pass it a new > > PyObject* to > > > >> manage (so it doesn't have to copy the PyObject* itself). > > > >> > > > >> I think that just means you can remove the "managingPyObject" > > function, > > > >> and instead use: > > > >> > > > >> object result(extract(copyable)()); > > > >> > > > >> > > > >> HTH > > > >> > > > >> Jim > > > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From talljimbo at gmail.com Sat Jun 9 03:22:47 2012 From: talljimbo at gmail.com (Jim Bosch) Date: Fri, 08 Jun 2012 21:22:47 -0400 Subject: [C++-sig] Properly copying wrapped classes In-Reply-To: References: <1338176220019-4630570.post@n4.nabble.com>, <4FC51407.30098.2E1EA6CE@s_sourceforge.nedprod.com> , <4FCB81F2.1000000@astro.princeton.edu> , <4FCCD9CA.9010400@astro.princeton.edu> , <4FD11993.1040406@astro.princeton.edu> Message-ID: <4FD2A567.2040902@gmail.com> It looks like the only way to get a wrapper object is by actually invoking the Python constructor. That's not what I expected, but it's reasonable and not completely unexpected. And it avoids problems that might arise if you had any Python-only attributes attached to the wrapper object. So I think you'll need to try a new approach, one that involves calling a wrapped copy constructor. Would it meet your needs to just remove the __copy__ and __deepcopy__ implementations, and change the Python derived class to something like what's below? class Der(BaseClass): def Test(self): print "Python Side Test. ID: " + str(self.GetID()) def Clone(self): print "Python Clone" result = Der(...) # whatever constructor args you need in Python BaseClass.__init__(result, self) return result (btw, apologies to the rest of the list - I accidentally replied without including the list a few emails back, but all you've missed are a number of ideas that don't work) Jim On 06/08/2012 08:40 PM, Jay Riley wrote: > I replaced my template copy with > > object bc_copy(object copyable, dict memo) > { > object copyMod = import("copy"); > object deepcopy = copyMod.attr("deepcopy"); > > BaseClassWrap *newCopyable(new BaseClassWrap(extract &>(copyable))); > > BaseClass tmp = boost::python::extract(copyable); > object result(tmp); > > int copyableId = (int)(copyable.ptr()); > memo[copyableId] = result; > > extract(result.attr("__dict__"))().update( > deepcopy(extract(copyable.attr("__dict__"))(), > memo)); > > return result; > } > > and wrapped > > class_ >("BaseClass", init<>()) > .def(init()) > .def(init()) > .def("GetID", &BaseClassWrap::GetIDDefault) > .def("Clone", &BaseClassWrap::CloneDefault) > .def("Test", &BaseClassWrap::TestDefault) > .def("__copy__", &generic__copy__< BaseClass >) > .def("__deepcopy__", &bc_copy) > ; > > But I'm still getting the non overriden behaviour. Calling Test on the > clone prints out the C++ side code, while the non clone prints out the > python side code. > > > > > > > Date: Thu, 7 Jun 2012 17:13:55 -0400 > > From: jbosch at astro.princeton.edu > > To: super24bitsound at hotmail.com > > Subject: Re: [C++-sig] Properly copying wrapped classes > > > > On 06/05/2012 12:41 AM, Jay Riley wrote: > > > That got rid of the compile time errors. However, On the python side I > > > get the following error when I try to clone: > > > > > > > > > File ... line 9 in Clone > > > return copy.deepcopy(self) > > > File C:\Python27\Lib\copy.py" line 174 in deepcopy > > > y = copier(memo) > > > TypeError: No to_python (by-value) converter for C++ type: class > > > BaseClassWrap > > > > > > > Hmm. I would have expected that to work. As long as BaseClass can be > > instantiated itself (i.e. it isn't pure abstract), you could try this in > > the copy/deepcopy implementation: > > > > BaseClass tmp = boost::python::extract(copyable); > > object result(tmp); > > > > (I don't remember which of these types your Copyable template parameter > > was, but I'd recommend just trying to write this in a non-template > > function until you get it working). > > > > That will involve one extra copy, but it should invoke the BaseClass > > by-value converter instead of the BaseClassWrap by-value converter, and > > I *think* that should do the right thing. > > > > > > Jim > > > > > > > > > > > In the interest of trying it out, I added the BaseClassWrap to the > > > python module > > > > > > class_ >("BaseClassWrap", > init()) > > > .def(init()) > > > .def(init()) > > > .def("__copy__", &generic__copy__< BaseClassWrap >) > > > .def("__deepcopy__", &generic__deepcopy__< BaseClassWrap >) > > > ; > > > > > > But this put me back at square one, where self isn't indicative of the > > > cloned instance. > > > > > > Just in the interest of seeing the effect, I changed my python > exposing to: > > > > > > class_ >("BaseClass", > init<>()) > > > .def(init()) > > > .def(init()) > > > .def("GetID", &BaseClassWrap::GetIDDefault) > > > .def("Clone", &BaseClassWrap::CloneDefault) > > > .def("Test", &BaseClassWrap::TestDefault) > > > .def("__copy__", &generic__copy__< BaseClass >) > > > .def("__deepcopy__", &generic__deepcopy__< BaseClass >) > > > ; > > > > > > But as expected, the overloading doesn't work on clones made with this > > > exposing. Anything else I should try? > > > > > > Again, thanks for the help so far, appreciate it. > > > > > > > > > > > > > > > > Date: Mon, 4 Jun 2012 11:52:42 -0400 > > > > From: jbosch at astro.princeton.edu > > > > To: super24bitsound at hotmail.com > > > > Subject: Re: [C++-sig] Properly copying wrapped classes > > > > > > > > On 06/04/2012 12:58 AM, Jay Riley wrote: > > > > > > > > > > Hi Jim, > > > > > Thanks for the help so far. From what you said, I should be able to > > > change my deepcopy to this correct? > > > > > > > > > > template object generic__deepcopy__(object > > > copyable, dict memo) { object copyMod = import("copy"); object deepcopy > > > = copyMod.attr("deepcopy"); > > > > > Copyable *newCopyable(new Copyable(extract > > &>(copyable))); //object > > > > result(boost::python::detail::new_reference(managingPyObject(newCopyable))); > > > > > object result(extract(copyable)()); > > > > > // HACK: copyableId shall be the same as the result of id(copyable) > > > //in Python - // please tell me that there is a better way! (and which > > > ;-p) int copyableId = (int)(copyable.ptr()); memo[copyableId] = result; > > > > > extract(result.attr("__dict__"))().update( > > > deepcopy(extract(copyable.attr("__dict__"))(), memo)); > > > > > return result; } > > > > > When I attempt to compile it gives me the following error: > > > > > Error 48 error C2664: 'boost::python::api::object::object(const > > > boost::python::api::object&)' : cannot convert parameter 1 from > > > 'boost::python::api::object (__cdecl *)(boost::python::extract > > > (__cdecl *)(void))' to 'const boost::python::api::object&' > > > c:\khmp\src\engine\scripting\python\scripthelpers.h 67 > > > > > Did you mean something else? This level of boost python is above my > > > head, so I'm a bit lost > > > > > > > > > > > > > It looks like the version I gave you is a bad corner case where the > > > > compiler is incapable of parsing a constructor properly when > templates > > > > and overloaded function-call operators are involved; I always forget > > > > exactly when that comes into play (not a compiler bug, just a > weird part > > > > of the standard, I think). In any case, I think separating it > into two > > > > lines should fix the problem: > > > > > > > > const Copyable & tmp = extract(copyable); > > > > object result(tmp); > > > > > > > > Let me know if that doesn't work either; at that point I should > try to > > > > compile it myself and see what's going on. > > > > > > > > Jim > > > > > > > > > > > > > > > > > > > > > > > > >> Date: Sun, 3 Jun 2012 11:25:38 -0400 > > > > >> From: jbosch at astro.princeton.edu > > > > >> To: cplusplus-sig at python.org > > > > >> CC: super24bitsound at hotmail.com > > > > >> Subject: Re: [C++-sig] Properly copying wrapped classes > > > > >> > > > > >> On 05/31/2012 08:49 PM, Jay Riley wrote: > > > > >>> I'm having a problem with some python objects derived in python. > > > I have > > > > >>> a Clone method that's supposed to make a full copy of these > python > > > > >>> inherited objects, but it isn't working. The problem is my > wrapper > > > > >>> class' PyObject* self isn't getting copied, so when I use > > > > >>> call_method<>(self, "method name"), self will never point to the > > > copied > > > > >>> instance. Here's a brief example showing the issue > > > > >>> > > > > >> > > > > >> > > > > >> > > > > >>> > > > > >>> Sorry about the length, just want to make sure I got everything > > > relevant > > > > >>> in. When I run this code, it prints: > > > > >>> > > > > >>> Python Clone > > > > >>> Python Side Test. ID: 1 > > > > >>> Python Side Test. ID: 1 > > > > >>> Original ID 1 > > > > >>> Clone ID 1 > > > > >>> > > > > >>> this is wrong because Clone ID should be 2 (inspecting the object > > > > >>> confirms it is 2). Like I said I'm pretty sure the problem is > > > that the > > > > >>> wrapper class' copy constructor only makes a copy of the > > > PyObject* self, > > > > >>> not a full copy. This is how every reference doc I saw was doing > > > class > > > > >>> wrapping, but isn't this wrong? Should we be making a full copy > > > of the > > > > >>> PyObject*? How would I go about doing that, or otherwise > modifying my > > > > >>> classes to get the behaviour I expect. > > > > >>> > > > > >> > > > > >> There are a couple of things here that probably need to be > addressed: > > > > >> > > > > >> - Be wary of relying on copy-constructor side effects to > demonstrate > > > > >> whether something is working; the compiler is allowed to elide > copy > > > > >> constructors under many conditions, which might result in > misleading > > > > >> results. That said, I don't think that's what's causing your > problem > > > > >> here (or at least not all of it). > > > > >> > > > > >> - Your implementations of __copy__ and __deepcopy__ won't work > with > > > > >> polymorphic wrapper classes, because they construct a BaseClass > > > instance > > > > >> and tell Boost.Python to wrap it by managing the new > reference. That > > > > >> necessarily makes a Python object that holds a BaseClass object, > > > not one > > > > >> that holds a BaseClassWrap object. If you want to get a > BaseClassWrap > > > > >> Python object, you want to pass it by value to Boost.Python; that > > > should > > > > >> invoke the BaseClassWrap copy constructor and pass it a new > > > PyObject* to > > > > >> manage (so it doesn't have to copy the PyObject* itself). > > > > >> > > > > >> I think that just means you can remove the "managingPyObject" > > > function, > > > > >> and instead use: > > > > >> > > > > >> object result(extract(copyable)()); > > > > >> > > > > >> > > > > >> HTH > > > > >> > > > > >> Jim > > > > > > > > > > > From talljimbo at gmail.com Sat Jun 9 03:43:53 2012 From: talljimbo at gmail.com (Jim Bosch) Date: Fri, 08 Jun 2012 21:43:53 -0400 Subject: [C++-sig] Boost::Python: overriding and smart pointers In-Reply-To: References: Message-ID: <4FD2AA59.80506@gmail.com> On 05/23/2012 10:21 AM, Sybren A. St?vel wrote: > Dear list, > > I'm trying to get my head around shared pointers combined with > overloaded methods. I want to create instances of my class both in > Python and C++, but for some reason I can't get both to work with the > same code. I've constructed a minimal example to show you what I'm > trying to do. The full C++ code with syntax highlighting can be found at > http://pastebin.com/ZqG79QUL > > Sorry for the long mail, but I saw no other way to show my issues in a > clear and unambiguous way. > > -------------------------------------- > class ExampleObject { > public: > std::string name; > > ExampleObject(const std::string & name) : name(name) {} > virtual ~ExampleObject() {} > virtual int some_number() { return 12; } > }; > > typedef boost::shared_ptr ExampleObjectPtr; > > ExampleObjectPtr create_example_object(const std::string & name) { > return boost::make_shared(name); > } > > void print_name(ExampleObjectPtr object) { > std::cout << "Example object named '" << object->name > << "', nr = " << object->some_number() > << std::endl; > } > -------------------------------------- > > These are the class and functions that I want to wrap. The > ExampleObject::some_number method should be overridable in Python. To > this end, I've created the following wrapper class: > > -------------------------------------- > struct ExampleObject_wrapper : ExampleObject, wrapper { > ExampleObject_wrapper(const std::string & name) > : ExampleObject(name), wrapper() > {} > > virtual int some_number(void) override { > if( override func_override = this->get_override("some_number")) > return func_override(); > return default_some_number(); > } > > int default_some_number(void) { > return this->ExampleObject::some_number(); > } > }; > > typedef boost::shared_ptr ExampleObject_wrapper_ptr; > -------------------------------------- > > The Python module is declared as follows: > > -------------------------------------- > BOOST_PYTHON_MODULE(wraptest) { > def("create_example_object", &create_example_object); > def("print_name", &print_name); > > class_ > ("ExampleObject", init()) > .def("some_number", &ExampleObject_wrapper::some_number, > &ExampleObject_wrapper::default_some_number) > ; > } > -------------------------------------- > > This is the Python code that I'm testing with: > > -------------------------------------- > from wraptest import * > > class ExampleSubclass(ExampleObject): > def some_number(self): > return ExampleObject.some_number(self) * 2 > > # Test from Python > from_py_obj = ExampleSubclass('from python') > print_name(from_py_obj) > > # Test from C++ > from_cpp = create_example_object('from C++') > print_name(from_cpp) > -------------------------------------- > > When I compile the module (VS2010, Python 3.2.2, Boost 1.48) and run the > Python script, I would expect the object created in C++ to show the > number 12, and the object created in Python to show the number 24. > However, the output is this: > > Example object named 'from python', nr = 12 > Example object named 'from C++', nr = 12 > > Running a debugger also shows that the ExampleObject_wrapper methods > aren't called at all. When I edit the class_<...> line by replacing > ExampleObjectPtr with ExampleObject_wrapper_ptr, the from-Python object > works just fine, but the from-C++ object gives me an exception: > > Example object named 'from python', nr = 24 > Traceback (most recent call last): > File "C:\workspace\rage\scripts\test_wrapping.py", line 13, in > from_cpp = create_example_object('from C++') > TypeError: No to_python (by-value) converter found for C++ type: class > boost::shared_ptr > > What should I do to be able to instantiate objects in C++ and Python alike? > I think this should do what you need: - Use ExampleObject_wrapper_ptr in the class_ declaration instead of ExampleObjectPtr. - Also register a converter for ExampleObjectPtr, with this line: register_ptr_from_python(); At least it works on my system (linux, Python 2.6). On my compiler (gcc 4.4) I also found it necessary to change your member function definition to the following: .def( "some_number", &ExampleObject::some_number, &ExampleObject_wrapper::default_some_number ) Without that, I couldn't get it to compile at all, which looked intentional, as the compile failure was clearly a compile-time assertion that the classes for the two member function pointers were not the same. Jim From srirangamnagaraju at gmail.com Sat Jun 9 07:58:29 2012 From: srirangamnagaraju at gmail.com (Nagaraju) Date: Sat, 9 Jun 2012 11:28:29 +0530 Subject: [C++-sig] Accessing Class Member Function from Python In-Reply-To: References: Message-ID: Hi Nat and All, I have created a TestProject.pyd file and imported it into Python as import TestProject planet = TestProject.MyClass() planet.add(1,1) When I execute the last statement, Python is giving following error: Traceback (most recent call last): File "", line 1, in planet.add(int(1),int(1)) ArgumentError: Python argument types in MyClass.add(MyClass, int, int) did not match C++ signature: add(int, int) Python version is: 2.7 Can anybody tell me how to resolve this issue? Thanks in advance. Regards, Raju. On Wed, Jun 6, 2012 at 7:08 PM, Nagaraju wrote: > Hi Nat, > > Thank you very much for the reply. > I tried making the target as ".pyd" and I am able to import it in Python > script. > > Thanks again. > > Regards, > Raju. > On Wed, Jun 6, 2012 at 6:57 PM, Nat Linden wrote: > >> On Wed, Jun 6, 2012 at 6:57 AM, Nagaraju >> wrote: >> >> > Thank you very much for your reply. I am sorry if I did not explain >> > something clearly. >> > >> > I am doing as below after implementing the MyClass in the same file: >> > >> > BOOST_PYTHON_MODULE(hello){ >> > ... >> > } >> > >> > I am using CDLL from ctypes to load this Test.DLL. Say >> > planet = CDLL("Test.DLL"). >> > >> > Now I want to create an object of MyClass and call add function. How >> can I >> > do this? >> >> I think you're mixing two different tactics here. >> >> You can use ctypes to load a plain DLL that publishes extern "C" >> functions, and call those functions. But I don't believe it supports >> the notion of a Python class defined in that DLL. >> >> Or you can use Boost.Python to prepare a special DLL that Python will >> recognize as an extension module. Such modules can be loaded with >> 'import'. In this case you don't use ctypes because the module >> contents describe themselves for the Python runtime to know how to use >> them directly, classes and methods and functions and data. >> Boost.Python is a succinct way to provide such a description. >> >> But it's my belief that a DLL containing the description compiled from >> BOOST_PYTHON_MODULE(hello) must be named "hello.pyd" for the Python >> interpreter to successfully import it. >> >> Once you're able to import hello, you should be able to instantiate >> hello.MyClass() and proceed from there. >> _______________________________________________ >> Cplusplus-sig mailing list >> Cplusplus-sig at python.org >> http://mail.python.org/mailman/listinfo/cplusplus-sig >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From srirangamnagaraju at gmail.com Sat Jun 9 10:20:37 2012 From: srirangamnagaraju at gmail.com (Nagaraju) Date: Sat, 9 Jun 2012 13:50:37 +0530 Subject: [C++-sig] Accessing Class Member Function from Python In-Reply-To: References: Message-ID: Hi All, Sorry for spamming. I got it worked. Regards, Raju. On Sat, Jun 9, 2012 at 11:28 AM, Nagaraju wrote: > Hi Nat and All, > > I have created a TestProject.pyd file and imported it into Python as > import TestProject > planet = TestProject.MyClass() > planet.add(1,1) > > When I execute the last statement, Python is giving following error: > Traceback (most recent call last): > File "", line 1, in > planet.add(int(1),int(1)) > ArgumentError: Python argument types in > MyClass.add(MyClass, int, int) > did not match C++ signature: > add(int, int) > > Python version is: 2.7 > Can anybody tell me how to resolve this issue? > > Thanks in advance. > > Regards, > Raju. > > On Wed, Jun 6, 2012 at 7:08 PM, Nagaraju wrote: > >> Hi Nat, >> >> Thank you very much for the reply. >> I tried making the target as ".pyd" and I am able to import it in Python >> script. >> >> Thanks again. >> >> Regards, >> Raju. >> On Wed, Jun 6, 2012 at 6:57 PM, Nat Linden wrote: >> >>> On Wed, Jun 6, 2012 at 6:57 AM, Nagaraju >>> wrote: >>> >>> > Thank you very much for your reply. I am sorry if I did not explain >>> > something clearly. >>> > >>> > I am doing as below after implementing the MyClass in the same file: >>> > >>> > BOOST_PYTHON_MODULE(hello){ >>> > ... >>> > } >>> > >>> > I am using CDLL from ctypes to load this Test.DLL. Say >>> > planet = CDLL("Test.DLL"). >>> > >>> > Now I want to create an object of MyClass and call add function. How >>> can I >>> > do this? >>> >>> I think you're mixing two different tactics here. >>> >>> You can use ctypes to load a plain DLL that publishes extern "C" >>> functions, and call those functions. But I don't believe it supports >>> the notion of a Python class defined in that DLL. >>> >>> Or you can use Boost.Python to prepare a special DLL that Python will >>> recognize as an extension module. Such modules can be loaded with >>> 'import'. In this case you don't use ctypes because the module >>> contents describe themselves for the Python runtime to know how to use >>> them directly, classes and methods and functions and data. >>> Boost.Python is a succinct way to provide such a description. >>> >>> But it's my belief that a DLL containing the description compiled from >>> BOOST_PYTHON_MODULE(hello) must be named "hello.pyd" for the Python >>> interpreter to successfully import it. >>> >>> Once you're able to import hello, you should be able to instantiate >>> hello.MyClass() and proceed from there. >>> _______________________________________________ >>> Cplusplus-sig mailing list >>> Cplusplus-sig at python.org >>> http://mail.python.org/mailman/listinfo/cplusplus-sig >>> >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From super24bitsound at hotmail.com Sun Jun 10 00:50:46 2012 From: super24bitsound at hotmail.com (Jay Riley) Date: Sat, 9 Jun 2012 18:50:46 -0400 Subject: [C++-sig] Properly copying wrapped classes In-Reply-To: <4FD2A567.2040902@gmail.com> References: <1338176220019-4630570.post@n4.nabble.com>, <4FC51407.30098.2E1EA6CE@s_sourceforge.nedprod.com> , <4FCB81F2.1000000@astro.princeton.edu> , <4FCCD9CA.9010400@astro.princeton.edu> , <4FD11993.1040406@astro.princeton.edu> , <4FD2A567.2040902@gmail.com> Message-ID: That'll work in the simplified example I had. But it's going to be a huge pain for many of my actual classes. I guess I'll have to do it like this if there's no other options? Though at that point I might need to limit how much functionality I'm exporting out to python. > Date: Fri, 8 Jun 2012 21:22:47 -0400 > From: talljimbo at gmail.com > To: super24bitsound at hotmail.com > CC: cplusplus-sig at python.org > Subject: Re: [C++-sig] Properly copying wrapped classes > > It looks like the only way to get a wrapper object is by actually > invoking the Python constructor. That's not what I expected, but it's > reasonable and not completely unexpected. And it avoids problems that > might arise if you had any Python-only attributes attached to the > wrapper object. > > So I think you'll need to try a new approach, one that involves calling > a wrapped copy constructor. > > Would it meet your needs to just remove the __copy__ and __deepcopy__ > implementations, and change the Python derived class to something like > what's below? > > class Der(BaseClass): > def Test(self): > print "Python Side Test. ID: " + str(self.GetID()) > > def Clone(self): > print "Python Clone" > result = Der(...) # whatever constructor args you need in Python > BaseClass.__init__(result, self) > return result > > > (btw, apologies to the rest of the list - I accidentally replied without > including the list a few emails back, but all you've missed are a number > of ideas that don't work) > > > Jim > > > > > > On 06/08/2012 08:40 PM, Jay Riley wrote: > > I replaced my template copy with > > > > object bc_copy(object copyable, dict memo) > > { > > object copyMod = import("copy"); > > object deepcopy = copyMod.attr("deepcopy"); > > > > BaseClassWrap *newCopyable(new BaseClassWrap(extract > &>(copyable))); > > > > BaseClass tmp = boost::python::extract(copyable); > > object result(tmp); > > > > int copyableId = (int)(copyable.ptr()); > > memo[copyableId] = result; > > > > extract(result.attr("__dict__"))().update( > > deepcopy(extract(copyable.attr("__dict__"))(), > > memo)); > > > > return result; > > } > > > > and wrapped > > > > class_ >("BaseClass", init<>()) > > .def(init()) > > .def(init()) > > .def("GetID", &BaseClassWrap::GetIDDefault) > > .def("Clone", &BaseClassWrap::CloneDefault) > > .def("Test", &BaseClassWrap::TestDefault) > > .def("__copy__", &generic__copy__< BaseClass >) > > .def("__deepcopy__", &bc_copy) > > ; > > > > But I'm still getting the non overriden behaviour. Calling Test on the > > clone prints out the C++ side code, while the non clone prints out the > > python side code. > > > > > > > > > > > > > Date: Thu, 7 Jun 2012 17:13:55 -0400 > > > From: jbosch at astro.princeton.edu > > > To: super24bitsound at hotmail.com > > > Subject: Re: [C++-sig] Properly copying wrapped classes > > > > > > On 06/05/2012 12:41 AM, Jay Riley wrote: > > > > That got rid of the compile time errors. However, On the python side I > > > > get the following error when I try to clone: > > > > > > > > > > > > File ... line 9 in Clone > > > > return copy.deepcopy(self) > > > > File C:\Python27\Lib\copy.py" line 174 in deepcopy > > > > y = copier(memo) > > > > TypeError: No to_python (by-value) converter for C++ type: class > > > > BaseClassWrap > > > > > > > > > > Hmm. I would have expected that to work. As long as BaseClass can be > > > instantiated itself (i.e. it isn't pure abstract), you could try this in > > > the copy/deepcopy implementation: > > > > > > BaseClass tmp = boost::python::extract(copyable); > > > object result(tmp); > > > > > > (I don't remember which of these types your Copyable template parameter > > > was, but I'd recommend just trying to write this in a non-template > > > function until you get it working). > > > > > > That will involve one extra copy, but it should invoke the BaseClass > > > by-value converter instead of the BaseClassWrap by-value converter, and > > > I *think* that should do the right thing. > > > > > > > > > Jim > > > > > > > > > > > > > > > > In the interest of trying it out, I added the BaseClassWrap to the > > > > python module > > > > > > > > class_ >("BaseClassWrap", > > init()) > > > > .def(init()) > > > > .def(init()) > > > > .def("__copy__", &generic__copy__< BaseClassWrap >) > > > > .def("__deepcopy__", &generic__deepcopy__< BaseClassWrap >) > > > > ; > > > > > > > > But this put me back at square one, where self isn't indicative of the > > > > cloned instance. > > > > > > > > Just in the interest of seeing the effect, I changed my python > > exposing to: > > > > > > > > class_ >("BaseClass", > > init<>()) > > > > .def(init()) > > > > .def(init()) > > > > .def("GetID", &BaseClassWrap::GetIDDefault) > > > > .def("Clone", &BaseClassWrap::CloneDefault) > > > > .def("Test", &BaseClassWrap::TestDefault) > > > > .def("__copy__", &generic__copy__< BaseClass >) > > > > .def("__deepcopy__", &generic__deepcopy__< BaseClass >) > > > > ; > > > > > > > > But as expected, the overloading doesn't work on clones made with this > > > > exposing. Anything else I should try? > > > > > > > > Again, thanks for the help so far, appreciate it. > > > > > > > > > > > > > > > > > > > > > Date: Mon, 4 Jun 2012 11:52:42 -0400 > > > > > From: jbosch at astro.princeton.edu > > > > > To: super24bitsound at hotmail.com > > > > > Subject: Re: [C++-sig] Properly copying wrapped classes > > > > > > > > > > On 06/04/2012 12:58 AM, Jay Riley wrote: > > > > > > > > > > > > Hi Jim, > > > > > > Thanks for the help so far. From what you said, I should be able to > > > > change my deepcopy to this correct? > > > > > > > > > > > > template object generic__deepcopy__(object > > > > copyable, dict memo) { object copyMod = import("copy"); object deepcopy > > > > = copyMod.attr("deepcopy"); > > > > > > Copyable *newCopyable(new Copyable(extract > > > &>(copyable))); //object > > > > > > result(boost::python::detail::new_reference(managingPyObject(newCopyable))); > > > > > > object result(extract(copyable)()); > > > > > > // HACK: copyableId shall be the same as the result of id(copyable) > > > > //in Python - // please tell me that there is a better way! (and which > > > > ;-p) int copyableId = (int)(copyable.ptr()); memo[copyableId] = result; > > > > > > extract(result.attr("__dict__"))().update( > > > > deepcopy(extract(copyable.attr("__dict__"))(), memo)); > > > > > > return result; } > > > > > > When I attempt to compile it gives me the following error: > > > > > > Error 48 error C2664: 'boost::python::api::object::object(const > > > > boost::python::api::object&)' : cannot convert parameter 1 from > > > > 'boost::python::api::object (__cdecl *)(boost::python::extract > > > > (__cdecl *)(void))' to 'const boost::python::api::object&' > > > > c:\khmp\src\engine\scripting\python\scripthelpers.h 67 > > > > > > Did you mean something else? This level of boost python is above my > > > > head, so I'm a bit lost > > > > > > > > > > > > > > > > It looks like the version I gave you is a bad corner case where the > > > > > compiler is incapable of parsing a constructor properly when > > templates > > > > > and overloaded function-call operators are involved; I always forget > > > > > exactly when that comes into play (not a compiler bug, just a > > weird part > > > > > of the standard, I think). In any case, I think separating it > > into two > > > > > lines should fix the problem: > > > > > > > > > > const Copyable & tmp = extract(copyable); > > > > > object result(tmp); > > > > > > > > > > Let me know if that doesn't work either; at that point I should > > try to > > > > > compile it myself and see what's going on. > > > > > > > > > > Jim > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > >> Date: Sun, 3 Jun 2012 11:25:38 -0400 > > > > > >> From: jbosch at astro.princeton.edu > > > > > >> To: cplusplus-sig at python.org > > > > > >> CC: super24bitsound at hotmail.com > > > > > >> Subject: Re: [C++-sig] Properly copying wrapped classes > > > > > >> > > > > > >> On 05/31/2012 08:49 PM, Jay Riley wrote: > > > > > >>> I'm having a problem with some python objects derived in python. > > > > I have > > > > > >>> a Clone method that's supposed to make a full copy of these > > python > > > > > >>> inherited objects, but it isn't working. The problem is my > > wrapper > > > > > >>> class' PyObject* self isn't getting copied, so when I use > > > > > >>> call_method<>(self, "method name"), self will never point to the > > > > copied > > > > > >>> instance. Here's a brief example showing the issue > > > > > >>> > > > > > >> > > > > > >> > > > > > >> > > > > > >>> > > > > > >>> Sorry about the length, just want to make sure I got everything > > > > relevant > > > > > >>> in. When I run this code, it prints: > > > > > >>> > > > > > >>> Python Clone > > > > > >>> Python Side Test. ID: 1 > > > > > >>> Python Side Test. ID: 1 > > > > > >>> Original ID 1 > > > > > >>> Clone ID 1 > > > > > >>> > > > > > >>> this is wrong because Clone ID should be 2 (inspecting the object > > > > > >>> confirms it is 2). Like I said I'm pretty sure the problem is > > > > that the > > > > > >>> wrapper class' copy constructor only makes a copy of the > > > > PyObject* self, > > > > > >>> not a full copy. This is how every reference doc I saw was doing > > > > class > > > > > >>> wrapping, but isn't this wrong? Should we be making a full copy > > > > of the > > > > > >>> PyObject*? How would I go about doing that, or otherwise > > modifying my > > > > > >>> classes to get the behaviour I expect. > > > > > >>> > > > > > >> > > > > > >> There are a couple of things here that probably need to be > > addressed: > > > > > >> > > > > > >> - Be wary of relying on copy-constructor side effects to > > demonstrate > > > > > >> whether something is working; the compiler is allowed to elide > > copy > > > > > >> constructors under many conditions, which might result in > > misleading > > > > > >> results. That said, I don't think that's what's causing your > > problem > > > > > >> here (or at least not all of it). > > > > > >> > > > > > >> - Your implementations of __copy__ and __deepcopy__ won't work > > with > > > > > >> polymorphic wrapper classes, because they construct a BaseClass > > > > instance > > > > > >> and tell Boost.Python to wrap it by managing the new > > reference. That > > > > > >> necessarily makes a Python object that holds a BaseClass object, > > > > not one > > > > > >> that holds a BaseClassWrap object. If you want to get a > > BaseClassWrap > > > > > >> Python object, you want to pass it by value to Boost.Python; that > > > > should > > > > > >> invoke the BaseClassWrap copy constructor and pass it a new > > > > PyObject* to > > > > > >> manage (so it doesn't have to copy the PyObject* itself). > > > > > >> > > > > > >> I think that just means you can remove the "managingPyObject" > > > > function, > > > > > >> and instead use: > > > > > >> > > > > > >> object result(extract(copyable)()); > > > > > >> > > > > > >> > > > > > >> HTH > > > > > >> > > > > > >> Jim > > > > > > > > > > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From sybren at stuvel.eu Mon Jun 11 11:12:14 2012 From: sybren at stuvel.eu (=?UTF-8?Q?Sybren_A=2E_St=C3=BCvel?=) Date: Mon, 11 Jun 2012 11:12:14 +0200 Subject: [C++-sig] Boost::Python: overriding and smart pointers In-Reply-To: <4FD2AA59.80506@gmail.com> References: <4FD2AA59.80506@gmail.com> Message-ID: Hi Jim, On 9 June 2012 03:43, Jim Bosch wrote: > - Use ExampleObject_wrapper_ptr in the class_ declaration instead of > ExampleObjectPtr. > > - Also register a converter for ExampleObjectPtr, with this line: > > register_ptr_from_python<**ExampleObjectPtr>(); > Yep, that did the trick. Thanks! > At least it works on my system (linux, Python 2.6). > Apparently it also works on Win7 with VS2010 and Python 3.2 ;-) Best, -- Sybren A. St?vel http://stuvel.eu/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From jjchristophe at yahoo.fr Mon Jun 11 11:26:18 2012 From: jjchristophe at yahoo.fr (christophe jean-joseph) Date: Mon, 11 Jun 2012 10:26:18 +0100 (BST) Subject: [C++-sig] Re : Re : changing argument value in a C++/Python code In-Reply-To: <4FD22552.6090006@seefeld.name> References: <1339148950.54266.YahooMailNeo@web132305.mail.ird.yahoo.com> <1339159573.12439.YahooMailNeo@web132303.mail.ird.yahoo.com> <4FD22552.6090006@seefeld.name> Message-ID: <1339406778.26008.YahooMailNeo@web132303.mail.ird.yahoo.com> Thank you very much for this hint. I didn't know about call policy. I have tested the different policies shown there: http://wiki.python.org/moin/boost.python/CallPolicy? http://www.boost.org/doc/libs/1_49_0/libs/python/doc/tutorial/doc/html/python/functions.? But all of them produce the same results: - myC is modified within Python, even after leaving the function - Python modification is not taken into account in C++ when h call g. I understand that call policies can be used in a more subtle way, but if you have any recommended link which is more explicit the the 2 former ones, that would be very helpful. Thank you very much in advance. CHRISTOPHE Jean-Joseph ________________________________ De?: Stefan Seefeld ??: cplusplus-sig at python.org Envoy? le : Vendredi 8 juin 2012 18h16 Objet?: Re: [C++-sig] Re : changing argument value in a C++/Python code Christoph, your C++ code passes a pointer argument to the "g()" member function, but your Python bindings don't specify a call policy. (I wonder why that doesn't raise a compilation error.) The effect mostly likely is that in fact the value is copied, so you see a new object. Explicit is better than implicit. ? ? Stefan -- ? ? ? ...ich hab' noch einen Koffer in Berlin... _______________________________________________ Cplusplus-sig mailing list Cplusplus-sig at python.org http://mail.python.org/mailman/listinfo/cplusplus-sig -------------- next part -------------- An HTML attachment was scrubbed... URL: From wichert at wiggy.net Wed Jun 13 12:31:46 2012 From: wichert at wiggy.net (Wichert Akkerman) Date: Wed, 13 Jun 2012 12:31:46 +0200 Subject: [C++-sig] bad exception conversion Message-ID: <4FD86C12.4030904@wiggy.net> I have some glue code that calls a C++ function which can raise an unsuitable_error exception. I have an exception translator which will convert that to a more pythonic version (UnsuitableError), but when I use that I get an "SystemError: 'finally' pops bad exception" error on the python side. As far as I can see my code looks correct, but I suspect I am overlooking something trivial somewhere. using namespace boost::python; class UnsuitableError : public std::exception { public: UnsuitableError() : reasons() { } ~UnsuitableError() throw() {} boost::python::list reasons; }; namespace { PyObject *UnsuitableErrorType = NULL; void translator(const unsuitable_error &e) { std::list::const_iterator i; PyObject* unicode; UnsuitableError error=UnsuitableError(); for (i=e.reasons.begin(); i!=e.reasons.end(); i++) { unicode = PyUnicode_FromString(*i); error.reasons.append(boost::python::object(boost::python::handle<>(unicode))); } boost::python::object exc(error); PyErr_SetObject(UnsuitableErrorType, exc.ptr()); } } void export() { object module(handle<>(borrowed(PyImport_AddModule("mypkg.article")))); scope().attr("article")=module; scope module_scope = module; class_ UnsuitableErrorClass("UnsuitableError"); UnsuitableErrorClass.def_readonly("reasons", &UnsuitableError::reasons); UnsuitableErrorType=UnsuitableErrorClass.ptr(); register_exception_translator(&translator); } From talljimbo at gmail.com Thu Jun 14 01:02:21 2012 From: talljimbo at gmail.com (Jim Bosch) Date: Wed, 13 Jun 2012 19:02:21 -0400 Subject: [C++-sig] bad exception conversion In-Reply-To: <4FD86C12.4030904@wiggy.net> References: <4FD86C12.4030904@wiggy.net> Message-ID: <4FD91BFD.2060101@gmail.com> On 06/13/2012 06:31 AM, Wichert Akkerman wrote: > I have some glue code that calls a C++ function which can raise an > unsuitable_error exception. I have an exception translator which will > convert that to a more pythonic version (UnsuitableError), but when I > use that I get an "SystemError: 'finally' pops bad exception" error on > the python side. As far as I can see my code looks correct, but I > suspect I am overlooking something trivial somewhere. > > > using namespace boost::python; > > class UnsuitableError : public std::exception { > public: > UnsuitableError() : reasons() { } > ~UnsuitableError() throw() {} > boost::python::list reasons; > }; > > namespace { > PyObject *UnsuitableErrorType = NULL; > > void translator(const unsuitable_error &e) { > std::list::const_iterator i; > PyObject* unicode; > UnsuitableError error=UnsuitableError(); > for (i=e.reasons.begin(); i!=e.reasons.end(); i++) { > unicode = PyUnicode_FromString(*i); > error.reasons.append(boost::python::object(boost::python::handle<>(unicode))); > > } > > boost::python::object exc(error); > PyErr_SetObject(UnsuitableErrorType, exc.ptr()); > } > } > > > void export() { > object > module(handle<>(borrowed(PyImport_AddModule("mypkg.article")))); > scope().attr("article")=module; > scope module_scope = module; > > class_ UnsuitableErrorClass("UnsuitableError"); > UnsuitableErrorClass.def_readonly("reasons", > &UnsuitableError::reasons); > UnsuitableErrorType=UnsuitableErrorClass.ptr(); > > register_exception_translator(&translator); > } I suspect the problem is that your custom exception doesn't derived from Python's built-in Exception base class. Unfortunately, it's impossible to do that with a Boost.Python wrapped class, but you can get it all done with the Python C API: namespace { PyObject *UnsuitableErrorType = NULL; void translator(const unsuitable_error &e) { std::list::const_iterator i; PyObject* unicode; boost::python::list reasons; for (i=e.reasons.begin(); i!=e.reasons.end(); i++) { boost::python::handle<> unicode(PyUnicode_FromString(*i)); reasons.append(boost::python::object(unicode)); } boost::python::handle<> error( PyObject_CallFunctionObjArgs( UnsuitableErrorType, NULL ) ); PyObject_SetAttrString(error.get(), "reasons", reasons.get()); PyErr_SetObject(UnsuitableErrorType, error.get()); } } void export() { object module(handle<>(borrowed(PyImport_AddModule("mypkg.article")))); scope().attr("article")=module; scope module_scope = module; // NOTE: can use something other than RuntimeError for base class UnsuitableErrorType = PyErr_NewException( "UnsuitableError", PyExc_RuntimeError, NULL ); module_scope.attr("UnsuitableError") = object(handle<>(borrowed(UnsuitableErrorType))); register_exception_translator(&translator); } I haven't tested any of that, but hopefully it's close enough to point you in the right direction. Jim From wichert at wiggy.net Thu Jun 14 11:19:32 2012 From: wichert at wiggy.net (Wichert Akkerman) Date: Thu, 14 Jun 2012 11:19:32 +0200 Subject: [C++-sig] bad exception conversion In-Reply-To: <4FD91BFD.2060101@gmail.com> References: <4FD86C12.4030904@wiggy.net> <4FD91BFD.2060101@gmail.com> Message-ID: <4FD9ACA4.2070409@wiggy.net> Hi Jim, On 06/14/2012 01:02 AM, Jim Bosch wrote: > I suspect the problem is that your custom exception doesn't derived > from Python's built-in Exception base class. Unfortunately, it's > impossible to do that with a Boost.Python wrapped class, but you can > get it all done with the Python C API: > > namespace { > PyObject *UnsuitableErrorType = NULL; > > void translator(const unsuitable_error &e) { > std::list::const_iterator i; > PyObject* unicode; > boost::python::list reasons; > for (i=e.reasons.begin(); i!=e.reasons.end(); i++) { > boost::python::handle<> unicode(PyUnicode_FromString(*i)); > reasons.append(boost::python::object(unicode)); > } For some odd reason that append line fails with this error: /usr/include/boost/python/converter/arg_to_python.hpp:194:7: instantiated from 'void boost::python::converter::detail::reject_raw_object_ptr(T*) [with T = _object]' /usr/include/boost/python/converter/arg_to_python.hpp:217:7: instantiated from 'boost::python::converter::detail::pointer_deep_arg_to_python::pointer_deep_arg_to_python(Ptr) [with Ptr = _object*]' /usr/include/boost/python/converter/arg_to_python.hpp:256:13: instantiated from 'boost::python::converter::arg_to_python::arg_to_python(const T&) [with T = _object*]' /usr/include/boost/python/object_core.hpp:393:69: instantiated from 'static PyObject* boost::python::api::object_initializer_impl::get(const T&, mpl_::false_) [with T = _object*, bool is_proxy = false, bool is_object_manager = false, PyObject = _object, mpl_::false_ = mpl_::bool_]' /usr/include/boost/python/object_core.hpp:315:7: instantiated from 'PyObject* boost::python::api::object_base_initializer(const T&) [with T = _object*, PyObject = _object]' /usr/include/boost/python/object_core.hpp:334:49: instantiated from 'boost::python::api::object::object(const T&) [with T = _object*]' ../../python/article.cc:23:48: instantiated from here /usr/include/boost/python/converter/arg_to_python.hpp:181:11: error: incomplete type 'boost::python::converter::detail::cannot_convert_raw_PyObject<_object*>' used in nested name specifier which is odd some it is essentially the same code as before, only with the reasons list moved out of a class into the local scope. > boost::python::handle<> error( > PyObject_CallFunctionObjArgs( > UnsuitableErrorType, NULL > ) > ); > PyObject_SetAttrString(error.get(), "reasons", reasons.get()); Small typo: reasons.ptr() there since reasons is an object, not a handle. > I haven't tested any of that, but hopefully it's close enough to point > you in the right direction. That's very helpful, thanks. Wichert. From wichert at wiggy.net Thu Jun 14 11:24:21 2012 From: wichert at wiggy.net (Wichert Akkerman) Date: Thu, 14 Jun 2012 11:24:21 +0200 Subject: [C++-sig] bad exception conversion In-Reply-To: <4FD9ACA4.2070409@wiggy.net> References: <4FD86C12.4030904@wiggy.net> <4FD91BFD.2060101@gmail.com> <4FD9ACA4.2070409@wiggy.net> Message-ID: <4FD9ADC5.3060507@wiggy.net> On 06/14/2012 11:19 AM, Wichert Akkerman wrote: > Hi Jim, > > On 06/14/2012 01:02 AM, Jim Bosch wrote: >> I suspect the problem is that your custom exception doesn't derived >> from Python's built-in Exception base class. Unfortunately, it's >> impossible to do that with a Boost.Python wrapped class, but you can >> get it all done with the Python C API: >> >> namespace { >> PyObject *UnsuitableErrorType = NULL; >> >> void translator(const unsuitable_error &e) { >> std::list::const_iterator i; >> PyObject* unicode; >> boost::python::list reasons; >> for (i=e.reasons.begin(); i!=e.reasons.end(); i++) { >> boost::python::handle<> unicode(PyUnicode_FromString(*i)); >> reasons.append(boost::python::object(unicode)); >> } > > For some odd reason that append line fails with this error: > > /usr/include/boost/python/converter/arg_to_python.hpp:194:7: > instantiated from 'void > boost::python::converter::detail::reject_raw_object_ptr(T*) [with T = > _object]' > /usr/include/boost/python/converter/arg_to_python.hpp:217:7: > instantiated from > 'boost::python::converter::detail::pointer_deep_arg_to_python::pointer_deep_arg_to_python(Ptr) > [with Ptr = _object*]' > /usr/include/boost/python/converter/arg_to_python.hpp:256:13: > instantiated from > 'boost::python::converter::arg_to_python::arg_to_python(const T&) > [with T = _object*]' > /usr/include/boost/python/object_core.hpp:393:69: instantiated from > 'static PyObject* > boost::python::api::object_initializer_impl is_object_manager>::get(const T&, mpl_::false_) [with T = _object*, > bool is_proxy = false, bool is_object_manager = false, PyObject = > _object, mpl_::false_ = mpl_::bool_]' > /usr/include/boost/python/object_core.hpp:315:7: instantiated from > 'PyObject* boost::python::api::object_base_initializer(const T&) [with > T = _object*, PyObject = _object]' > /usr/include/boost/python/object_core.hpp:334:49: instantiated from > 'boost::python::api::object::object(const T&) [with T = _object*]' > ../../python/article.cc:23:48: instantiated from here > /usr/include/boost/python/converter/arg_to_python.hpp:181:11: error: > incomplete type > 'boost::python::converter::detail::cannot_convert_raw_PyObject<_object*>' > used in nested name specifier > > which is odd some it is essentially the same code as before, only with > the reasons list moved out of a class into the local scope. Stupid copy & paste error on my side - I forgot the handle bit :( Regards, Wichert. From s_sourceforge at nedprod.com Thu Jun 14 14:33:26 2012 From: s_sourceforge at nedprod.com (Niall Douglas) Date: Thu, 14 Jun 2012 13:33:26 +0100 Subject: [C++-sig] bad exception conversion In-Reply-To: <4FD91BFD.2060101@gmail.com> References: <4FD86C12.4030904@wiggy.net>, <4FD91BFD.2060101@gmail.com> Message-ID: <4FD9DA16.12220.7F44C4A2@s_sourceforge.nedprod.com> Do you think that this answer is worth adding to the BPL FAQ? Normally you don't need to derive from Python's Exception object, and indeed in my own custom exception implementations I never did so. However, if this has changed, an FAQ entry is appropriate. Ideally, a wishlist work item would map std::exception onto Python's Exception, so if you inherit from std::exception it appears as Python's Exception. I was just reading last night in Nicolai Josuttis' C++11 updated "The C++ Standard Library" how very much easier this has become to implement in C++11. The only fault with that book so far is it makes me want to dump old compilers right now. Niall On 13 Jun 2012 at 19:02, Jim Bosch wrote: > On 06/13/2012 06:31 AM, Wichert Akkerman wrote: > > I have some glue code that calls a C++ function which can raise an > > unsuitable_error exception. I have an exception translator which will > > convert that to a more pythonic version (UnsuitableError), but when I > > use that I get an "SystemError: 'finally' pops bad exception" error on > > the python side. As far as I can see my code looks correct, but I > > suspect I am overlooking something trivial somewhere. > > > > > > using namespace boost::python; > > > > class UnsuitableError : public std::exception { > > public: > > UnsuitableError() : reasons() { } > > ~UnsuitableError() throw() {} > > boost::python::list reasons; > > }; > > > > namespace { > > PyObject *UnsuitableErrorType = NULL; > > > > void translator(const unsuitable_error &e) { > > std::list::const_iterator i; > > PyObject* unicode; > > UnsuitableError error=UnsuitableError(); > > for (i=e.reasons.begin(); i!=e.reasons.end(); i++) { > > unicode = PyUnicode_FromString(*i); > > error.reasons.append(boost::python::object(boost::python::handle<>(unicode))); > > > > } > > > > boost::python::object exc(error); > > PyErr_SetObject(UnsuitableErrorType, exc.ptr()); > > } > > } > > > > > > void export() { > > object > > module(handle<>(borrowed(PyImport_AddModule("mypkg.article")))); > > scope().attr("article")=module; > > scope module_scope = module; > > > > class_ UnsuitableErrorClass("UnsuitableError"); > > UnsuitableErrorClass.def_readonly("reasons", > > &UnsuitableError::reasons); > > UnsuitableErrorType=UnsuitableErrorClass.ptr(); > > > > register_exception_translator(&translator); > > } > > I suspect the problem is that your custom exception doesn't derived from > Python's built-in Exception base class. Unfortunately, it's impossible > to do that with a Boost.Python wrapped class, but you can get it all > done with the Python C API: > > namespace { > PyObject *UnsuitableErrorType = NULL; > > void translator(const unsuitable_error &e) { > std::list::const_iterator i; > PyObject* unicode; > boost::python::list reasons; > for (i=e.reasons.begin(); i!=e.reasons.end(); i++) { > boost::python::handle<> unicode(PyUnicode_FromString(*i)); > reasons.append(boost::python::object(unicode)); > } > boost::python::handle<> error( > PyObject_CallFunctionObjArgs( > UnsuitableErrorType, NULL > ) > ); > PyObject_SetAttrString(error.get(), "reasons", reasons.get()); > PyErr_SetObject(UnsuitableErrorType, error.get()); > } > } > > > void export() { > object module(handle<>(borrowed(PyImport_AddModule("mypkg.article")))); > scope().attr("article")=module; > scope module_scope = module; > > // NOTE: can use something other than RuntimeError for base class > UnsuitableErrorType = PyErr_NewException( > "UnsuitableError", PyExc_RuntimeError, NULL > ); > module_scope.attr("UnsuitableError") = > object(handle<>(borrowed(UnsuitableErrorType))); > > register_exception_translator(&translator); > } > > > I haven't tested any of that, but hopefully it's close enough to point > you in the right direction. > > > Jim > _______________________________________________ > Cplusplus-sig mailing list > Cplusplus-sig at python.org > http://mail.python.org/mailman/listinfo/cplusplus-sig -- Technology & Consulting Services - ned Productions Limited. http://www.nedproductions.biz/. VAT reg: IE 9708311Q. Work Portfolio: http://careers.stackoverflow.com/nialldouglas/ From wichert at wiggy.net Thu Jun 14 15:01:33 2012 From: wichert at wiggy.net (Wichert Akkerman) Date: Thu, 14 Jun 2012 15:01:33 +0200 Subject: [C++-sig] bad exception conversion In-Reply-To: <4FD9DA16.12220.7F44C4A2@s_sourceforge.nedprod.com> References: <4FD86C12.4030904@wiggy.net>, <4FD91BFD.2060101@gmail.com> <4FD9DA16.12220.7F44C4A2@s_sourceforge.nedprod.com> Message-ID: <4FD9E0AD.3030607@wiggy.net> On 06/14/2012 02:33 PM, Niall Douglas wrote: > Do you think that this answer is worth adding to the BPL FAQ? > Normally you don't need to derive from Python's Exception object, and > indeed in my own custom exception implementations I never did so. > However, if this has changed, an FAQ entry is appropriate. Python is certainly going in that direction. You used to be able to do all kinds of crazy things such as using strings as exceptions but current versions are much stricter about what you can raise. This is what Python 2 says: >>> raise "hell" Traceback (most recent call last): File "", line 1, in TypeError: exceptions must be old-style classes or derived from BaseException, not str and here is Python 3: >>> raise "the dead" Traceback (most recent call last): File "", line 1, in TypeError: exceptions must derive from BaseException Wichert. From s_sourceforge at nedprod.com Thu Jun 14 15:35:28 2012 From: s_sourceforge at nedprod.com (Niall Douglas) Date: Thu, 14 Jun 2012 14:35:28 +0100 Subject: [C++-sig] bad exception conversion In-Reply-To: <4FD9E0AD.3030607@wiggy.net> References: <4FD86C12.4030904@wiggy.net>, <4FD9DA16.12220.7F44C4A2@s_sourceforge.nedprod.com>, <4FD9E0AD.3030607@wiggy.net> Message-ID: <4FD9E8A0.7183.7F7D9010@s_sourceforge.nedprod.com> On 14 Jun 2012 at 15:01, Wichert Akkerman wrote: > On 06/14/2012 02:33 PM, Niall Douglas wrote: > > Do you think that this answer is worth adding to the BPL FAQ? > > Normally you don't need to derive from Python's Exception object, and > > indeed in my own custom exception implementations I never did so. > > However, if this has changed, an FAQ entry is appropriate. > > Python is certainly going in that direction. You used to be able to do > all kinds of crazy things such as using strings as exceptions but > current versions are much stricter about what you can raise. This is > what Python 2 says: C++ is going in that direction too :) >From my own perspective, inheriting std::exception says that you comply with std::exception and you want your exceptions to be categorised as a std::exception. In my custom exception handling, I definitely did not want that as my exceptions could do fun stuff like aggregrate themselves when being multiply rethrown during destructor unwinds, something I still think C++11 gives up too easily upon. Maybe if I get my exception handling support into ISO C I might finally win that argument :) Now I vaguely remember something on this list about 3k needing to inherit from BaseException, and that broke BPL. I vaguely remember the solution Dave or somebody suggested was to wire in a BaseException inheritance on 3k only and not on 2k for backwards compatibility. I absolutely agree we need a policy in BPL which fixes this properly. Niall -- Technology & Consulting Services - ned Productions Limited. http://www.nedproductions.biz/. VAT reg: IE 9708311Q. Work Portfolio: http://careers.stackoverflow.com/nialldouglas/ From presentisgood at gmail.com Sat Jun 16 17:57:56 2012 From: presentisgood at gmail.com (vikas chauhan) Date: Sat, 16 Jun 2012 21:42:56 +0545 Subject: [C++-sig] wrapping generic getter/setter functions in boost.python Message-ID: Hi all, I am pretty new to boost.python and I have been getting some problems wrapping generic getter/setter functions. Say for eg. we have class like this. class X{ int a[10]; public: int geta(int index) throw(some_exception) { if(index >= 10 || index <0) throw some_exception; return a[index]; } void seta(int index, int val) throw(some_exception) { if(index >= 10 || index < 0) throw some_exception; a[index] = value; } }; I want to add attributes like a0, a1, a2,.. a9 in my python class, wherein a0 corresponds to a[0] , a1 to a[1] and likewise. In the boost.python docs ( exposing Class properties ), getter/settter functions are documented for single value only. Is it possible to do what I want ( i.e add separate attributes using the single geta()/seta() functions ) or I need to write some kind of wrapper functions (each for accessing each a[i]) ? i.e, what I want to do is something like this. BOOST_PYTHON_MODULE(mymod) { using namespace boost::python; class_("X") .add_property("a0", &X::geta, &X::seta) .add_property("a1", &X::geta, &X::seta) .. .. ; } and passing the arguments to geta ( i.e 0, 1,.. etc ) in someway. So, basically what I want is , to avoid unnecessary code bloat. regards, vikas -------------- next part -------------- An HTML attachment was scrubbed... URL: From j.wielicki at sotecware.net Sat Jun 16 18:14:34 2012 From: j.wielicki at sotecware.net (Jonas Wielicki) Date: Sat, 16 Jun 2012 18:14:34 +0200 Subject: [C++-sig] wrapping generic getter/setter functions in boost.python In-Reply-To: References: Message-ID: <4FDCB0EA.3000504@sotecware.net> On 16.06.2012 17:57, vikas chauhan wrote: > Is it possible to do what I want ( i.e add separate attributes using the > single geta()/seta() functions ) or I need to write some kind of wrapper > functions (each for accessing each a[i]) ? I guess the simplest way to do that is to template the geta and seta function similar to this one: class X { template int geta() throw(foo) { return a[index]; } // ... } you then somehow need to force instanciation I guess, maybe a plain // ... .add_property("a0", &X::geta<0>) does the trick, but I doubt it. This just as a suggestion for a direction to do research in, I did not try it, neither I would bet that it works ;) cheers, Jonas From presentisgood at gmail.com Sun Jun 17 18:31:18 2012 From: presentisgood at gmail.com (vikas chauhan) Date: Sun, 17 Jun 2012 22:16:18 +0545 Subject: [C++-sig] Cplusplus-sig Digest, Vol 45, Issue 15 In-Reply-To: References: Message-ID: On 17 June 2012 15:45, wrote: > Send Cplusplus-sig mailing list submissions to > cplusplus-sig at python.org > > To subscribe or unsubscribe via the World Wide Web, visit > http://mail.python.org/mailman/listinfo/cplusplus-sig > or, via email, send a message with subject or body 'help' to > cplusplus-sig-request at python.org > > You can reach the person managing the list at > cplusplus-sig-owner at python.org > > When replying, please edit your Subject line so it is more specific > than "Re: Contents of Cplusplus-sig digest..." > > > Today's Topics: > > 1. wrapping generic getter/setter functions in boost.python > (vikas chauhan) > 2. Re: wrapping generic getter/setter functions in boost.python > (Jonas Wielicki) > > > ---------------------------------------------------------------------- > > Message: 1 > Date: Sat, 16 Jun 2012 21:42:56 +0545 > From: vikas chauhan > To: cplusplus-sig at python.org > Subject: [C++-sig] wrapping generic getter/setter functions in > boost.python > Message-ID: > > > Content-Type: text/plain; charset="iso-8859-1" > > Hi all, > I am pretty new to boost.python and I have been getting some problems > wrapping generic getter/setter functions. > Say for eg. we have class like this. > > class X{ > int a[10]; > public: > int geta(int index) throw(some_exception) { > if(index >= 10 || index <0) > throw some_exception; > return a[index]; > } > void seta(int index, int val) throw(some_exception) { > if(index >= 10 || index < 0) > throw some_exception; > a[index] = value; > } > }; > > I want to add attributes like a0, a1, a2,.. a9 in my python class, wherein > a0 corresponds to a[0] , a1 to a[1] and likewise. > In the boost.python docs ( exposing Class properties ), getter/settter > functions are documented for single value only. > Is it possible to do what I want ( i.e add separate attributes using the > single geta()/seta() functions ) or I need to write some kind of wrapper > functions (each for accessing each a[i]) ? > > i.e, what I want to do is something like this. > > BOOST_PYTHON_MODULE(mymod) > { > using namespace boost::python; > > class_("X") > .add_property("a0", &X::geta, &X::seta) > .add_property("a1", &X::geta, &X::seta) > .. > .. > ; > } > > and passing the arguments to geta ( i.e 0, 1,.. etc ) in someway. > > So, basically what I want is , to avoid unnecessary code bloat. > > regards, > vikas > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: < > http://mail.python.org/pipermail/cplusplus-sig/attachments/20120616/53a515d4/attachment-0001.html > > > > ------------------------------ > > Message: 2 > Date: Sat, 16 Jun 2012 18:14:34 +0200 > From: Jonas Wielicki > To: Development of Python/C++ integration > Subject: Re: [C++-sig] wrapping generic getter/setter functions in > boost.python > Message-ID: <4FDCB0EA.3000504 at sotecware.net> > Content-Type: text/plain; charset=UTF-8 > > On 16.06.2012 17:57, vikas chauhan wrote: > > Is it possible to do what I want ( i.e add separate attributes using the > > single geta()/seta() functions ) or I need to write some kind of wrapper > > functions (each for accessing each a[i]) ? > I guess the simplest way to do that is to template the geta and seta > function similar to this one: > > class X { > template > int geta() throw(foo) { > return a[index]; > } > // ... > } > > you then somehow need to force instanciation I guess, maybe a plain > > // ... > .add_property("a0", &X::geta<0>) > > does the trick, but I doubt it. This just as a suggestion for a > direction to do research in, I did not try it, neither I would bet that > it works ;) > > cheers, > Jonas > > > ------------------------------ > > _______________________________________________ > Cplusplus-sig mailing list > Cplusplus-sig at python.org > http://mail.python.org/mailman/listinfo/cplusplus-sig > > End of Cplusplus-sig Digest, Vol 45, Issue 15 > ********************************************* > Hi Jonas, thanks a lot for your suggestions. It actually worked !! cheers, vikas -------------- next part -------------- An HTML attachment was scrubbed... URL: From presentisgood at gmail.com Wed Jun 20 19:37:18 2012 From: presentisgood at gmail.com (vikas chauhan) Date: Wed, 20 Jun 2012 23:22:18 +0545 Subject: [C++-sig] Cplusplus-sig Digest, Vol 45, Issue 15 In-Reply-To: References: Message-ID: On 17 June 2012 22:16, vikas chauhan wrote: > > > On 17 June 2012 15:45, wrote: > >> Send Cplusplus-sig mailing list submissions to >> cplusplus-sig at python.org >> >> To subscribe or unsubscribe via the World Wide Web, visit >> http://mail.python.org/mailman/listinfo/cplusplus-sig >> or, via email, send a message with subject or body 'help' to >> cplusplus-sig-request at python.org >> >> You can reach the person managing the list at >> cplusplus-sig-owner at python.org >> >> When replying, please edit your Subject line so it is more specific >> than "Re: Contents of Cplusplus-sig digest..." >> >> >> Today's Topics: >> >> 1. wrapping generic getter/setter functions in boost.python >> (vikas chauhan) >> 2. Re: wrapping generic getter/setter functions in boost.python >> (Jonas Wielicki) >> >> >> ---------------------------------------------------------------------- >> >> Message: 1 >> Date: Sat, 16 Jun 2012 21:42:56 +0545 >> From: vikas chauhan >> To: cplusplus-sig at python.org >> Subject: [C++-sig] wrapping generic getter/setter functions in >> boost.python >> Message-ID: >> < >> CAG2Q8SbD4CgEH9gx9mNj6XYArEtp5vqL_wUtfo6AiQnZCPR-Eg at mail.gmail.com> >> Content-Type: text/plain; charset="iso-8859-1" >> >> Hi all, >> I am pretty new to boost.python and I have been getting some problems >> wrapping generic getter/setter functions. >> Say for eg. we have class like this. >> >> class X{ >> int a[10]; >> public: >> int geta(int index) throw(some_exception) { >> if(index >= 10 || index <0) >> throw some_exception; >> return a[index]; >> } >> void seta(int index, int val) throw(some_exception) { >> if(index >= 10 || index < 0) >> throw some_exception; >> a[index] = value; >> } >> }; >> >> I want to add attributes like a0, a1, a2,.. a9 in my python class, wherein >> a0 corresponds to a[0] , a1 to a[1] and likewise. >> In the boost.python docs ( exposing Class properties ), getter/settter >> functions are documented for single value only. >> Is it possible to do what I want ( i.e add separate attributes using the >> single geta()/seta() functions ) or I need to write some kind of wrapper >> functions (each for accessing each a[i]) ? >> >> i.e, what I want to do is something like this. >> >> BOOST_PYTHON_MODULE(mymod) >> { >> using namespace boost::python; >> >> class_("X") >> .add_property("a0", &X::geta, &X::seta) >> .add_property("a1", &X::geta, &X::seta) >> .. >> .. >> ; >> } >> >> and passing the arguments to geta ( i.e 0, 1,.. etc ) in someway. >> >> So, basically what I want is , to avoid unnecessary code bloat. >> >> regards, >> vikas >> -------------- next part -------------- >> An HTML attachment was scrubbed... >> URL: < >> http://mail.python.org/pipermail/cplusplus-sig/attachments/20120616/53a515d4/attachment-0001.html >> > >> >> ------------------------------ >> >> Message: 2 >> Date: Sat, 16 Jun 2012 18:14:34 +0200 >> From: Jonas Wielicki >> To: Development of Python/C++ integration >> Subject: Re: [C++-sig] wrapping generic getter/setter functions in >> boost.python >> Message-ID: <4FDCB0EA.3000504 at sotecware.net> >> Content-Type: text/plain; charset=UTF-8 >> >> On 16.06.2012 17:57, vikas chauhan wrote: >> > Is it possible to do what I want ( i.e add separate attributes using >> the >> > single geta()/seta() functions ) or I need to write some kind of wrapper >> > functions (each for accessing each a[i]) ? >> I guess the simplest way to do that is to template the geta and seta >> function similar to this one: >> >> class X { >> template >> int geta() throw(foo) { >> return a[index]; >> } >> // ... >> } >> >> you then somehow need to force instanciation I guess, maybe a plain >> >> // ... >> .add_property("a0", &X::geta<0>) >> >> does the trick, but I doubt it. This just as a suggestion for a >> direction to do research in, I did not try it, neither I would bet that >> it works ;) >> >> cheers, >> Jonas >> >> >> ------------------------------ >> >> _______________________________________________ >> Cplusplus-sig mailing list >> Cplusplus-sig at python.org >> http://mail.python.org/mailman/listinfo/cplusplus-sig >> >> End of Cplusplus-sig Digest, Vol 45, Issue 15 >> ********************************************* >> > > Hi Jonas, > thanks a lot for your suggestions. It actually worked !! > > cheers, > vikas > Hi, there is one more thing. In the above wrapped python class, the attributes a0, a1 etc will appear under class X. what if I want to group these attributes in another class ( thus adding an extra level hierarchy between X and the attributes ) object which itself is an attribute of X. i.e I don't want X.a0, X.a1 etc, but something like X.y.a0, X.y.a1 , where y is a dummy class object. Is there any way to do that ? I tried using scopes and all that, but it didn't work. cheers, vikas -------------- next part -------------- An HTML attachment was scrubbed... URL: From srirangamnagaraju at gmail.com Thu Jun 21 06:31:07 2012 From: srirangamnagaraju at gmail.com (Nagaraju) Date: Thu, 21 Jun 2012 10:01:07 +0530 Subject: [C++-sig] Specified procedure could not be found Message-ID: Hi All, I have written a C++ DLL. That DLL depends on some other libraries. I have kept all those dependent libraries in the release folder. Now in a seperate project in Visual Studio 2008, I used BOOST Python and called a function from one of the classes in C++ DLL. It is compiling fine (compiling it as .pyd), but when I try to import this in python with "import PythonSample", it is throwing following error. Import Error: DLL Load Failed: The specified procedure could not be found. Can you tell me, how to find what went wrong? I tried googling it, but could not find suitable solution. I am using Python 2.7 version. Thanks for your time. Regards, Raju. -------------- next part -------------- An HTML attachment was scrubbed... URL: From s_sourceforge at nedprod.com Thu Jun 21 11:00:33 2012 From: s_sourceforge at nedprod.com (Niall Douglas) Date: Thu, 21 Jun 2012 10:00:33 +0100 Subject: [C++-sig] Specified procedure could not be found In-Reply-To: References: Message-ID: <4FE2E2B1.23039.A28E9177@s_sourceforge.nedprod.com> You might find Microsoft's Dependency Walker useful. http://www.dependencywalker.com/ Niall On 21 Jun 2012 at 10:01, Nagaraju wrote: > Hi All, > > I have written a C++ DLL. That DLL depends on some other libraries. I have > kept all those dependent libraries in the release folder. > > Now in a seperate project in Visual Studio 2008, I used BOOST Python and > called a function from one of the classes in C++ DLL. > > It is compiling fine (compiling it as .pyd), but when I try to import this > in python with "import PythonSample", it is throwing following error. > > Import Error: DLL Load Failed: The specified procedure could not be found. > > Can you tell me, how to find what went wrong? I tried googling it, but > could not find suitable solution. > > I am using Python 2.7 version. > > Thanks for your time. > > Regards, > Raju. > -- Technology & Consulting Services - ned Productions Limited. http://www.nedproductions.biz/. VAT reg: IE 9708311Q. Work Portfolio: http://careers.stackoverflow.com/nialldouglas/ From srirangamnagaraju at gmail.com Thu Jun 21 11:04:17 2012 From: srirangamnagaraju at gmail.com (Nagaraju) Date: Thu, 21 Jun 2012 14:34:17 +0530 Subject: [C++-sig] Specified procedure could not be found In-Reply-To: <4FE2E2B1.23039.A28E9177@s_sourceforge.nedprod.com> References: <4FE2E2B1.23039.A28E9177@s_sourceforge.nedprod.com> Message-ID: Hi Niall, I have used the DW and all the libraries are present. The same code works, if I use LoadLibrary in C++. But when I try to build the C++ DLL code with extention ".pyd", it is throwing error. FYI, the C++ Class names are mangled. Regards, Raju. On Thu, Jun 21, 2012 at 2:30 PM, Niall Douglas wrote: > You might find Microsoft's Dependency Walker useful. > > http://www.dependencywalker.com/ > > Niall > > > On 21 Jun 2012 at 10:01, Nagaraju wrote: > > > Hi All, > > > > I have written a C++ DLL. That DLL depends on some other libraries. I > have > > kept all those dependent libraries in the release folder. > > > > Now in a seperate project in Visual Studio 2008, I used BOOST Python and > > called a function from one of the classes in C++ DLL. > > > > It is compiling fine (compiling it as .pyd), but when I try to import > this > > in python with "import PythonSample", it is throwing following error. > > > > Import Error: DLL Load Failed: The specified procedure could not be > found. > > > > Can you tell me, how to find what went wrong? I tried googling it, but > > could not find suitable solution. > > > > I am using Python 2.7 version. > > > > Thanks for your time. > > > > Regards, > > Raju. > > > > > -- > Technology & Consulting Services - ned Productions Limited. > http://www.nedproductions.biz/. VAT reg: IE 9708311Q. > Work Portfolio: http://careers.stackoverflow.com/nialldouglas/ > _______________________________________________ > Cplusplus-sig mailing list > Cplusplus-sig at python.org > http://mail.python.org/mailman/listinfo/cplusplus-sig > -------------- next part -------------- An HTML attachment was scrubbed... URL: From s_sourceforge at nedprod.com Thu Jun 21 11:53:39 2012 From: s_sourceforge at nedprod.com (Niall Douglas) Date: Thu, 21 Jun 2012 10:53:39 +0100 Subject: [C++-sig] Specified procedure could not be found In-Reply-To: References: , <4FE2E2B1.23039.A28E9177@s_sourceforge.nedprod.com>, Message-ID: <4FE2EF23.31599.A2BF2F92@s_sourceforge.nedprod.com> With DW it's not so much that the libraries are present, but to check that there are no failed symbol imports. Your error suggests a failed symbol import. Niall On 21 Jun 2012 at 14:34, Nagaraju wrote: > Hi Niall, > > I have used the DW and all the libraries are present. > > The same code works, if I use LoadLibrary in C++. But when I try to build > the C++ DLL code with extention ".pyd", it is throwing error. > > FYI, the C++ Class names are mangled. > > Regards, > Raju. > > On Thu, Jun 21, 2012 at 2:30 PM, Niall Douglas wrote: > > > You might find Microsoft's Dependency Walker useful. > > > > http://www.dependencywalker.com/ > > > > Niall > > > > > > On 21 Jun 2012 at 10:01, Nagaraju wrote: > > > > > Hi All, > > > > > > I have written a C++ DLL. That DLL depends on some other libraries. I > > have > > > kept all those dependent libraries in the release folder. > > > > > > Now in a seperate project in Visual Studio 2008, I used BOOST Python and > > > called a function from one of the classes in C++ DLL. > > > > > > It is compiling fine (compiling it as .pyd), but when I try to import > > this > > > in python with "import PythonSample", it is throwing following error. > > > > > > Import Error: DLL Load Failed: The specified procedure could not be > > found. > > > > > > Can you tell me, how to find what went wrong? I tried googling it, but > > > could not find suitable solution. > > > > > > I am using Python 2.7 version. > > > > > > Thanks for your time. > > > > > > Regards, > > > Raju. > > > > > > > > > -- > > Technology & Consulting Services - ned Productions Limited. > > http://www.nedproductions.biz/. VAT reg: IE 9708311Q. > > Work Portfolio: http://careers.stackoverflow.com/nialldouglas/ > > _______________________________________________ > > Cplusplus-sig mailing list > > Cplusplus-sig at python.org > > http://mail.python.org/mailman/listinfo/cplusplus-sig > > > -- Technology & Consulting Services - ned Productions Limited. http://www.nedproductions.biz/. VAT reg: IE 9708311Q. Work Portfolio: http://careers.stackoverflow.com/nialldouglas/ From srirangamnagaraju at gmail.com Thu Jun 21 12:09:01 2012 From: srirangamnagaraju at gmail.com (Nagaraju) Date: Thu, 21 Jun 2012 15:39:01 +0530 Subject: [C++-sig] Specified procedure could not be found In-Reply-To: <4FE2EF23.31599.A2BF2F92@s_sourceforge.nedprod.com> References: <4FE2E2B1.23039.A28E9177@s_sourceforge.nedprod.com> <4FE2EF23.31599.A2BF2F92@s_sourceforge.nedprod.com> Message-ID: Hi Niall, Thanks a lot for your time. I checked all the DLL's. Everything is showing ok. Only one is, IEFrame.DLL and in that for one function it is showing red in color. Function name as "#270". We are not using that function/DLL anways. Regards, Raju. On Thu, Jun 21, 2012 at 3:23 PM, Niall Douglas wrote: > With DW it's not so much that the libraries are present, but to check > that there are no failed symbol imports. Your error suggests a failed > symbol import. > > Niall > > On 21 Jun 2012 at 14:34, Nagaraju wrote: > > > Hi Niall, > > > > I have used the DW and all the libraries are present. > > > > The same code works, if I use LoadLibrary in C++. But when I try to build > > the C++ DLL code with extention ".pyd", it is throwing error. > > > > FYI, the C++ Class names are mangled. > > > > Regards, > > Raju. > > > > On Thu, Jun 21, 2012 at 2:30 PM, Niall Douglas < > s_sourceforge at nedprod.com>wrote: > > > > > You might find Microsoft's Dependency Walker useful. > > > > > > http://www.dependencywalker.com/ > > > > > > Niall > > > > > > > > > On 21 Jun 2012 at 10:01, Nagaraju wrote: > > > > > > > Hi All, > > > > > > > > I have written a C++ DLL. That DLL depends on some other libraries. I > > > have > > > > kept all those dependent libraries in the release folder. > > > > > > > > Now in a seperate project in Visual Studio 2008, I used BOOST Python > and > > > > called a function from one of the classes in C++ DLL. > > > > > > > > It is compiling fine (compiling it as .pyd), but when I try to import > > > this > > > > in python with "import PythonSample", it is throwing following error. > > > > > > > > Import Error: DLL Load Failed: The specified procedure could not be > > > found. > > > > > > > > Can you tell me, how to find what went wrong? I tried googling it, > but > > > > could not find suitable solution. > > > > > > > > I am using Python 2.7 version. > > > > > > > > Thanks for your time. > > > > > > > > Regards, > > > > Raju. > > > > > > > > > > > > > -- > > > Technology & Consulting Services - ned Productions Limited. > > > http://www.nedproductions.biz/. VAT reg: IE 9708311Q. > > > Work Portfolio: http://careers.stackoverflow.com/nialldouglas/ > > > _______________________________________________ > > > Cplusplus-sig mailing list > > > Cplusplus-sig at python.org > > > http://mail.python.org/mailman/listinfo/cplusplus-sig > > > > > > > > -- > Technology & Consulting Services - ned Productions Limited. > http://www.nedproductions.biz/. VAT reg: IE 9708311Q. > Work Portfolio: http://careers.stackoverflow.com/nialldouglas/ > _______________________________________________ > Cplusplus-sig mailing list > Cplusplus-sig at python.org > http://mail.python.org/mailman/listinfo/cplusplus-sig > -------------- next part -------------- An HTML attachment was scrubbed... URL: From s_sourceforge at nedprod.com Thu Jun 21 14:24:07 2012 From: s_sourceforge at nedprod.com (Niall Douglas) Date: Thu, 21 Jun 2012 13:24:07 +0100 Subject: [C++-sig] Specified procedure could not be found In-Reply-To: References: , <4FE2EF23.31599.A2BF2F92@s_sourceforge.nedprod.com>, Message-ID: <4FE31267.5913.CD622@s_sourceforge.nedprod.com> Doesn't matter if you use it, if it's linked then something you're using is using it. If it isn't lazy linked, just one failed symbol import will fail the whole DLL dependency tree. No idea what might cause that in your case, maybe there's a mixing of different versions of system DLLs by various dependencies. Welcome to DLL hell! I'd suggest you eliminate dependencies until the problem goes away. Start by lazy linking anything not absolutely necessary (though this pushes the fatal exit into the runtime). Also, check a fresh install of Windows inside a virtual machine. You'll often find the problem isn't there, in which case it's a problem on your development machine. Maybe time for a wipe and reinstall if that's the case, saves time in the long run. Niall On 21 Jun 2012 at 15:39, Nagaraju wrote: > Hi Niall, > > Thanks a lot for your time. > > I checked all the DLL's. Everything is showing ok. Only one is, IEFrame.DLL > and in that for one function it is showing red in color. Function name as > "#270". > > We are not using that function/DLL anways. > > Regards, > Raju. > > On Thu, Jun 21, 2012 at 3:23 PM, Niall Douglas wrote: > > > With DW it's not so much that the libraries are present, but to check > > that there are no failed symbol imports. Your error suggests a failed > > symbol import. > > > > Niall > > > > On 21 Jun 2012 at 14:34, Nagaraju wrote: > > > > > Hi Niall, > > > > > > I have used the DW and all the libraries are present. > > > > > > The same code works, if I use LoadLibrary in C++. But when I try to build > > > the C++ DLL code with extention ".pyd", it is throwing error. > > > > > > FYI, the C++ Class names are mangled. > > > > > > Regards, > > > Raju. > > > > > > On Thu, Jun 21, 2012 at 2:30 PM, Niall Douglas < > > s_sourceforge at nedprod.com>wrote: > > > > > > > You might find Microsoft's Dependency Walker useful. > > > > > > > > http://www.dependencywalker.com/ > > > > > > > > Niall > > > > > > > > > > > > On 21 Jun 2012 at 10:01, Nagaraju wrote: > > > > > > > > > Hi All, > > > > > > > > > > I have written a C++ DLL. That DLL depends on some other libraries. I > > > > have > > > > > kept all those dependent libraries in the release folder. > > > > > > > > > > Now in a seperate project in Visual Studio 2008, I used BOOST Python > > and > > > > > called a function from one of the classes in C++ DLL. > > > > > > > > > > It is compiling fine (compiling it as .pyd), but when I try to import > > > > this > > > > > in python with "import PythonSample", it is throwing following error. > > > > > > > > > > Import Error: DLL Load Failed: The specified procedure could not be > > > > found. > > > > > > > > > > Can you tell me, how to find what went wrong? I tried googling it, > > but > > > > > could not find suitable solution. > > > > > > > > > > I am using Python 2.7 version. > > > > > > > > > > Thanks for your time. > > > > > > > > > > Regards, > > > > > Raju. > > > > > > > > > > > > > > > > > -- > > > > Technology & Consulting Services - ned Productions Limited. > > > > http://www.nedproductions.biz/. VAT reg: IE 9708311Q. > > > > Work Portfolio: http://careers.stackoverflow.com/nialldouglas/ > > > > _______________________________________________ > > > > Cplusplus-sig mailing list > > > > Cplusplus-sig at python.org > > > > http://mail.python.org/mailman/listinfo/cplusplus-sig > > > > > > > > > > > > > -- > > Technology & Consulting Services - ned Productions Limited. > > http://www.nedproductions.biz/. VAT reg: IE 9708311Q. > > Work Portfolio: http://careers.stackoverflow.com/nialldouglas/ > > _______________________________________________ > > Cplusplus-sig mailing list > > Cplusplus-sig at python.org > > http://mail.python.org/mailman/listinfo/cplusplus-sig > > > -- Technology & Consulting Services - ned Productions Limited. http://www.nedproductions.biz/. VAT reg: IE 9708311Q. Work Portfolio: http://careers.stackoverflow.com/nialldouglas/ From trigves at yahoo.com Thu Jun 21 23:31:53 2012 From: trigves at yahoo.com (Trigve Siver) Date: Thu, 21 Jun 2012 14:31:53 -0700 (PDT) Subject: [C++-sig] C++ clas with (*args, **kwargs) constructor Message-ID: <1340314313.63339.YahooMailNeo@web110408.mail.gq1.yahoo.com> Hi, I'm trying to find some solution to my problem but without succes. I need to be able to export C++ class constructor that takes arbitraty arguments (as in python __init__(self, *args, **kwargs). Is it possible to have this kind of constructor? I've tried something like this: BOOST_PYTHON_MODULE(main) { class_>("Form") ; } then in main: ... try { ????????object?main?=?import("__main__"); object?global(main.attr("__dict__")); boost::python::dict?local; ??? ??? exec(?? "import?main\n" "class?Form1(main.Form):\n" "?def?__init__(self,?A,?*args,?**kwargs):\n" "??super().__init__(*args,?**kwargs)\n\n" ,?global,?local); //?Get class object?c_form1?=?local["Form1"]; //?Create?instance object?form1_instance?=?object(handle<>(PyObject_CallObject(c_form1.ptr(),?make_tuple(1,?2).ptr()))); } catch(error_already_set?&) { PyErr_Print(); } But it prints: Traceback (most recent call last): File "", line 4, in __init__ Boost.Python.ArgumentError: Python argument types in Form.__init__(Form1, int) did not match C++ signature: __init__(struct _object *) Which is logical I think because it finds only default constructor. I've tried also raw_constructor from http://wiki.python.org/moin/boost.python/HowTo#A.22Raw.22_constructor but without success. Anyone know if it is somehow possible? Thanks Trigve From trigves at yahoo.com Thu Jun 21 23:35:12 2012 From: trigves at yahoo.com (Trigve Siver) Date: Thu, 21 Jun 2012 14:35:12 -0700 (PDT) Subject: [C++-sig] C++ clas with (*args, **kwargs) constructor In-Reply-To: <1340314313.63339.YahooMailNeo@web110408.mail.gq1.yahoo.com> References: <1340314313.63339.YahooMailNeo@web110408.mail.gq1.yahoo.com> Message-ID: <1340314512.62753.YahooMailNeo@web110409.mail.gq1.yahoo.com> > From: Trigve Siver > To: Development of Python/C++ integration > Cc: > Sent: Thursday, June 21, 2012 11:31 PM > Subject: [C++-sig] C++ clas with (*args, **kwargs) constructor > > ... > then in main: > ... > try { > ????????object?main?=?import("__main__"); > object?global(main.attr("__dict__")); boost::python::dict?local; > ??? ??? exec(?? "import?main\n" > "class?Form1(main.Form):\n" > "?def?__init__(self,?A,?*args,?**kwargs):\n" > "??super().__init__(*args,?**kwargs)\n\n" ,?global,?local); > //?Get class object?c_form1?=?local["Form1"]; //?Create?instance > object?form1_instance?=?object(handle<>(PyObject_CallObject(c_form1.ptr(),?make_tuple(1,?2).ptr()))); > } > catch(error_already_set?&) > { PyErr_Print(); > } Bad formatting, sorry: try { ????????object?main?=?import("__main__"); ??? ??? object?global(main.attr("__dict__")); ??? ??? boost::python::dict?local; ??? ??? exec("import?main\n" ??? ??? ??? "class?Form1(main.Form):\n" ??????? ??? "?def?__init__(self,?A,?*args,?**kwargs):\n" ??? ??????? "??super().__init__(*args,?**kwargs)\n\n" ??? ??? ??? ,?global,?local); ??? ??? //?Get class ??? ??? object?c_form1?=?local["Form1"]; ??? ??? //?Create?instance ??? ??? object?form1_instance?=?object(handle<>(PyObject_CallObject(c_form1.ptr(),?make_tuple(1,?2).ptr()))); } catch(error_already_set?&) { ??? PyErr_Print(); } ? >... Trigve From talljimbo at gmail.com Thu Jun 21 23:57:23 2012 From: talljimbo at gmail.com (Jim Bosch) Date: Thu, 21 Jun 2012 17:57:23 -0400 Subject: [C++-sig] C++ clas with (*args, **kwargs) constructor In-Reply-To: <1340314313.63339.YahooMailNeo@web110408.mail.gq1.yahoo.com> References: <1340314313.63339.YahooMailNeo@web110408.mail.gq1.yahoo.com> Message-ID: <4FE398C3.8020400@gmail.com> On 06/21/2012 05:31 PM, Trigve Siver wrote: > > > Hi, > I'm trying to find some solution to my problem but without succes. I need to be able to export C++ class constructor that takes arbitraty arguments (as in python __init__(self, *args, **kwargs). Is it possible to have this kind of constructor? I've tried something like this: > I believe this is not possible in Boost.Python. The closest approximations I know of are: - Use a static method or free function instead of a constructor for this mode of construction in Python. You can wrap a non-constructor with *args, **kwds using boost::python::raw_function. - Inherit from the wrapped class at the Python layer; the derived class could then have a constructor with *args, **kwds. Jim From brandsmeier at gmx.de Thu Jun 21 23:58:16 2012 From: brandsmeier at gmx.de (Holger Brandsmeier) Date: Thu, 21 Jun 2012 23:58:16 +0200 Subject: [C++-sig] C++ clas with (*args, **kwargs) constructor In-Reply-To: <1340314313.63339.YahooMailNeo@web110408.mail.gq1.yahoo.com> References: <1340314313.63339.YahooMailNeo@web110408.mail.gq1.yahoo.com> Message-ID: Trigve, with the line class_>("Form") ; you declare Form to have a default constructor (you didn't use any init<> struct. That is why you can not pass anything to the constructor. If you want to use a constructor with a single (but arbitrary) type, then you should use PyObject on the C++ side. Try to get this working and tell us if this is how you want it to work, I have a feeling that you already might not like having to manually convert the PyObject* to the proper types. However, you can not avoid it, you can not expect boost::python to automatically call a constructor taking a single `int` if all that you export is a constructor taking one `PyObject`, you will have to do the proper conversions on the C++ side. Second if you want to work with many objects of type PyObject* or even `kwargs`, then http://wiki.python.org/moin/boost.python/HowTo#A.22Raw.22_constructor is one option. I didn't really do this myself, but what is your problem there? Possibly another object is, if you change the python side from super().__init__(*args, **kwargs) to super().__init__(args, kwargs) then you can write a C++ constructor which expects `list` and `dict` and you will exactly find the contents of args passed as `list` and `kwargs` as `dict`. -Holger On Thu, Jun 21, 2012 at 11:31 PM, Trigve Siver wrote: > > > Hi, > I'm trying to find some solution to my problem but without succes. I need to be able to export C++ class constructor that takes arbitraty arguments (as in python __init__(self, *args, **kwargs). Is it possible to have this kind of constructor? I've tried something like this: > > BOOST_PYTHON_MODULE(main) > { class_>("Form") ; > } > > then in main: > ... > try { > ????????object?main?=?import("__main__"); object?global(main.attr("__dict__")); boost::python::dict?local; > ??? ??? exec(?? "import?main\n" "class?Form1(main.Form):\n" "?def?__init__(self,?A,?*args,?**kwargs):\n" "??super().__init__(*args,?**kwargs)\n\n" ,?global,?local); //?Get class object?c_form1?=?local["Form1"]; //?Create?instance object?form1_instance?=?object(handle<>(PyObject_CallObject(c_form1.ptr(),?make_tuple(1,?2).ptr()))); > } > catch(error_already_set?&) > { PyErr_Print(); > } > > But it prints: > Traceback (most recent call last): > File "", line 4, in __init__ > Boost.Python.ArgumentError: Python argument types in > Form.__init__(Form1, int) > did not match C++ signature: > __init__(struct _object *) > > Which is logical I think because it finds only default constructor. I've tried also raw_constructor from http://wiki.python.org/moin/boost.python/HowTo#A.22Raw.22_constructor but without success. > > Anyone know if it is somehow possible? > > Thanks > > Trigve > > _______________________________________________ > Cplusplus-sig mailing list > Cplusplus-sig at python.org > http://mail.python.org/mailman/listinfo/cplusplus-sig From trigves at yahoo.com Fri Jun 22 00:07:40 2012 From: trigves at yahoo.com (Trigve Siver) Date: Thu, 21 Jun 2012 15:07:40 -0700 (PDT) Subject: [C++-sig] C++ clas with (*args, **kwargs) constructor In-Reply-To: <4FE398C3.8020400@gmail.com> References: <1340314313.63339.YahooMailNeo@web110408.mail.gq1.yahoo.com> <4FE398C3.8020400@gmail.com> Message-ID: <1340316460.89110.YahooMailNeo@web110407.mail.gq1.yahoo.com> > From: Jim Bosch > To: cplusplus-sig at python.org > Cc: > Sent: Thursday, June 21, 2012 11:57 PM > Subject: Re: [C++-sig] C++ clas with (*args, **kwargs) constructor > > On 06/21/2012 05:31 PM, Trigve Siver wrote: >> >> >> Hi, >> I'm trying to find some solution to my problem but without succes. I > need to be able to export C++ class constructor that takes arbitraty arguments > (as in python __init__(self, *args, **kwargs). Is it possible to have this kind > of constructor? I've tried something like this: >> > > I believe this is not possible in Boost.Python.? The closest approximations I > know of are: > > - Use a static method or free function instead of a constructor for this mode of > construction in Python.? You can wrap a non-constructor with *args, **kwds using > boost::python::raw_function. > > - Inherit from the wrapped class at the Python layer; the derived class could > then have a constructor with *args, **kwds. > Thanks for reply :) Hmm I was trying with python::raw_function, but without success also. Ok I'm gonna try a bit more with raw_constructor once more. Thanks > > Jim Trigve From trigves at yahoo.com Fri Jun 22 00:15:57 2012 From: trigves at yahoo.com (Trigve Siver) Date: Thu, 21 Jun 2012 15:15:57 -0700 (PDT) Subject: [C++-sig] C++ clas with (*args, **kwargs) constructor In-Reply-To: References: <1340314313.63339.YahooMailNeo@web110408.mail.gq1.yahoo.com> Message-ID: <1340316957.99389.YahooMailNeo@web110409.mail.gq1.yahoo.com> > From: Holger Brandsmeier > To: Trigve Siver ; Development of Python/C++ integration > Cc: > Sent: Thursday, June 21, 2012 11:58 PM > Subject: Re: [C++-sig] C++ clas with (*args, **kwargs) constructor > >T rigve, > > with the line > ? > class_>("Form") > ; > you declare Form to have a default constructor (you didn't use any > init<> struct. That is why you can not pass anything to the > constructor. If you want to use a constructor with a single (but > arbitrary) type, then you should use PyObject on the C++ side. Try to > get this working and tell us if this is how you want it to work, I > have a feeling that you already might not like having to manually > convert the PyObject* to the proper types. However, you can not avoid > it, you can not expect boost::python to automatically call a > constructor taking a single `int` if all that you export is a > constructor taking one `PyObject`, you will have to do the proper > conversions on the C++ side. > > Second if you want to work with many objects of type PyObject* or even > `kwargs`, then > ? http://wiki.python.org/moin/boost.python/HowTo#A.22Raw.22_constructor > is one option. I didn't really do this myself, but what is your problem > there? Thanks for reply :) Ok it looks like it is working now :) When I used raw_constructor I have set min arguments to 2, like this: ... boost::shared_ptr
create(tuple, dict) { ??? return boost::shared_ptr(new Form()); } class_>("Form", no_init) ??? ??? .def("__init__", raw_constructor(&create, 2)) ... But when *args or **kwargs was empty (or both of them),? it was spoiling errors. So I set min arguments to 0 (removed the parameter respectively). Hope I'm doing it right way. >? ... > > -Holger > Thanks Trigve From talljimbo at gmail.com Fri Jun 22 00:28:37 2012 From: talljimbo at gmail.com (Jim Bosch) Date: Thu, 21 Jun 2012 18:28:37 -0400 Subject: [C++-sig] C++ clas with (*args, **kwargs) constructor In-Reply-To: <1340316460.89110.YahooMailNeo@web110407.mail.gq1.yahoo.com> References: <1340314313.63339.YahooMailNeo@web110408.mail.gq1.yahoo.com> <4FE398C3.8020400@gmail.com> <1340316460.89110.YahooMailNeo@web110407.mail.gq1.yahoo.com> Message-ID: <4FE3A015.1040400@gmail.com> On 06/21/2012 06:07 PM, Trigve Siver wrote: >> From: Jim Bosch >> To: cplusplus-sig at python.org >> Cc: >> Sent: Thursday, June 21, 2012 11:57 PM >> Subject: Re: [C++-sig] C++ clas with (*args, **kwargs) constructor >> >> On 06/21/2012 05:31 PM, Trigve Siver wrote: >>> >>> >>> Hi, >>> I'm trying to find some solution to my problem but without succes. I >> need to be able to export C++ class constructor that takes arbitraty arguments >> (as in python __init__(self, *args, **kwargs). Is it possible to have this kind >> of constructor? I've tried something like this: >>> >> >> I believe this is not possible in Boost.Python. The closest approximations I >> know of are: >> >> - Use a static method or free function instead of a constructor for this mode of >> construction in Python. You can wrap a non-constructor with *args, **kwds using >> boost::python::raw_function. >> >> - Inherit from the wrapped class at the Python layer; the derived class could >> then have a constructor with *args, **kwds. >> > > Thanks for reply :) Hmm I was trying with python::raw_function, but without success also. Ok I'm gonna try a bit more with raw_constructor once more. > Heh, I didn't even know about raw_constructor, because it isn't in the reference docs for some reason. If it exists, then your problem very likely is solvable and my response was totally bogus. Glad I didn't discourage you. Jim From trigves at yahoo.com Fri Jun 22 00:43:47 2012 From: trigves at yahoo.com (Trigve Siver) Date: Thu, 21 Jun 2012 15:43:47 -0700 (PDT) Subject: [C++-sig] C++ clas with (*args, **kwargs) constructor In-Reply-To: <4FE3A015.1040400@gmail.com> References: <1340314313.63339.YahooMailNeo@web110408.mail.gq1.yahoo.com> <4FE398C3.8020400@gmail.com> <1340316460.89110.YahooMailNeo@web110407.mail.gq1.yahoo.com> <4FE3A015.1040400@gmail.com> Message-ID: <1340318627.50623.YahooMailNeo@web110413.mail.gq1.yahoo.com> > From: Jim Bosch > To: cplusplus-sig at python.org > Cc: > Sent: Friday, June 22, 2012 12:28 AM > Subject: Re: [C++-sig] C++ clas with (*args, **kwargs) constructor > > On 06/21/2012 06:07 PM, Trigve Siver wrote: >>> From: Jim Bosch >>> To: cplusplus-sig at python.org >>> Cc: >>> Sent: Thursday, June 21, 2012 11:57 PM >>> Subject: Re: [C++-sig] C++ clas with (*args, **kwargs) constructor >>> >>> On 06/21/2012 05:31 PM, Trigve Siver wrote: >>>> >>>> >>>> ? Hi, >>>> ? I'm trying to find some solution to my problem but without > succes. I >>> need to be able to export C++ class constructor that takes arbitraty > arguments >>> (as in python __init__(self, *args, **kwargs). Is it possible to have > this kind >>> of constructor? I've tried something like this: >>>> >>> >>> I believe this is not possible in Boost.Python.? The closest > approximations I >>> know of are: >>> >>> - Use a static method or free function instead of a constructor for > this mode of >>> construction in Python.? You can wrap a non-constructor with *args, > **kwds using >>> boost::python::raw_function. >>> >>> - Inherit from the wrapped class at the Python layer; the derived class > could >>> then have a constructor with *args, **kwds. >>> >> >> Thanks for reply :) Hmm I was trying with python::raw_function, but without > success also. Ok I'm gonna try a bit more with raw_constructor once more. >> > > Heh, I didn't even know about raw_constructor, because it isn't in the > reference docs for some reason.? If it exists, then your problem very > likely is solvable and my response was totally bogus. This raw_constructor isn't integrated in boost:python. It is from http://wiki.python.org/moin/boost.python/HowTo#A.22Raw.22_constructor as mentioned in previous mail. Maybe there is a little chance to make patch and add it to boost::python? :) > Glad I didn't discourage you. :) > > Jim Trigve