From tr.ernie.l at gmail.com Thu Apr 2 21:05:53 2015 From: tr.ernie.l at gmail.com (Ernie Lee) Date: Thu, 2 Apr 2015 13:05:53 -0600 Subject: [C++-sig] Memory management in Boost.Python In-Reply-To: References: <54FF0B26.70105@seefeld.name> <54FFDA25.5070504@seefeld.name> Message-ID: Also, i found that i manually call 'Py_XINCREF' on callback object (ie on 'a1' in this example) then script is terminating without errors and do not see destructor call for a1 object (but i guess later one is expected). Thoughts? On Sun, Mar 15, 2015 at 6:11 PM, Ernie Lee wrote: > Hi Stefan, > > I tried to create minimal tests and it turned out that there might be > two separate issues here: one related to memory management and other to > subclassing C++ classes in Python (i will post the subclassing example in > separate mail). > > Running code below as-is works fine and i can see printed message > generated by ?A? class destructor. However commenting out line > ?reset_callback()? in Python code will lead to a segfault and also no call > to ?A? class destructor occur. Thoughts? > > Thanks, > > > Ernie. > > > Python code: ???????? > from callback2 import * > > a1 = A() > a1.info() > set_callback(a1) > test_callback() > reset_callback() > > C++ code: ?????????? > include > #include > #include > > class A > { > public: > virtual ~A() { std::cout << "A destructor for object: " << this << > std::endl; } > > virtual void info() { std::cout << "C++ A info for object" << this << > std::endl; } > }; > > static boost::shared_ptr current_callback; > > void set_callback(boost::shared_ptr a) {current_callback = a; } > > void reset_callback() { current_callback = boost::shared_ptr(); } > > void test_callback() > { > std::cout << "test_callback: "; > if(current_callback) current_callback->info(); > else std::cout << "Callback is NULL!" << std::endl; > } > > > BOOST_PYTHON_MODULE(callback2) > { > boost::python::class_, boost::noncopyable>("A") > .def("info", &A::info) > ; > > boost::python::def("set_callback", set_callback); > boost::python::def("reset_callback", reset_callback); > boost::python::def("test_callback", test_callback); > } > ???????????????? > > > On Wed, Mar 11, 2015 at 12:01 AM, Stefan Seefeld > wrote: > >> On 10/03/15 11:24 PM, Ernie Lee wrote: >> > Hi Stefan, >> > >> > I updated my code so it now use 'boost::shared_ptr' class while >> > specifying the held-type and i got exactly the same errors (i guess >> > boost did recognize class even in different namespace). >> > >> > Any other theories of what could be wrong? Could it be that Python >> > in some cases tries to manage memory directly, disregarding SP layer? >> >> In that case I suggest you narrow down the failure into a minimal test >> case and send that to the list. Otherwise this would be highly >> speculative and thus inefficient. >> >> Regards, >> Stefan >> >> -- >> >> ...ich hab' noch einen Koffer in Berlin... >> >> _______________________________________________ >> Cplusplus-sig mailing list >> Cplusplus-sig at python.org >> https://mail.python.org/mailman/listinfo/cplusplus-sig >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From giuseppe.corbelli at copanitalia.com Fri Apr 3 10:16:56 2015 From: giuseppe.corbelli at copanitalia.com (Giuseppe Corbelli) Date: Fri, 03 Apr 2015 10:16:56 +0200 Subject: [C++-sig] Passing std::wstring to Python callback In-Reply-To: <0FB1C672-F116-492B-B85D-A5E11547CC27@gmail.com> References: <0FB1C672-F116-492B-B85D-A5E11547CC27@gmail.com> Message-ID: <551E4C78.7080700@copanitalia.com> On 18/03/2015 22:25, Bogdan Cristea wrote: > > Hi > > I am using boost python for providing python bindings for a C++ library. I am > using Python 2.7. My library needs to call callbacks that are defined in > Python. There callbacks can take a string parameter. C++ side I am always > using std::wstring. Everything works on as long as std::wstring contains only > ASCII chars, but once I get something like ??? my application crashes. This > issue seems to be related to the way I pass std::wstring to Python callbacks: > as long as I make sure that the passed string has only ASCII chars it is ok. > My problem is how do I pass unicode strings to Python. Late reply, I know... Have a look at boost/python/converter/builtin_converters.hpp You should find something like #if defined(Py_USING_UNICODE) && !defined(BOOST_NO_STD_WSTRING) BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::wstring, ::PyUnicode_FromWideChar(x.data(),implicit_cast(x.size())), &PyUnicode_Type) # endif PyUnicode_FromWideChar returns NULL on failure, so a SEGV may as well be expected. AFAIK an UTF16 encoding should be OK. -- Giuseppe Corbelli WASP Software Engineer, Copan Italia S.p.A Phone: +390303666318 Fax: +390302659932 E-mail: giuseppe.corbelli at copanitalia.com From schueller.p at gmail.com Thu Apr 2 21:12:49 2015 From: schueller.p at gmail.com (=?UTF-8?Q?Peter_Sch=C3=BCller?=) Date: Thu, 2 Apr 2015 22:12:49 +0300 Subject: [C++-sig] subprocess fork() sometimes hangs when called from within boost::python::exec_file Message-ID: Dear all, In the hexhex project on github [1] we execute a python program using boost::python::exec_file, the respective code is in src/PythonPlugin.cpp in the function PythonPlugin::runPythonMain(...). In this python program I use subprocess.call() to run a shell application (actually graphviz). Sometimes it works, sometimes it hangs using 100% CPU. It seems to depend on how much the C++ program had to do before it executed the python part. In both cases the C++ program uses threads (is that relevant wrt. fork() in python? I found some hints online that it could be relevant). I traced it down to os.fork() in subprocess.py which returns in one case and does not return at all (neither parent nor child) in the other case. If I do strace -f on the process I get the following (the SIGPROF/rt_sigreturn/clone repeats until the disk is full): [pid 18646] clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f96a5fa2a50) = ? ERESTARTNOINTR (To be restarted) [pid 18646] --- SIGPROF {si_signo=SIGPROF, si_code=SI_KERNEL} --- [pid 18646] rt_sigreturn() = 56 [pid 18646] clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f96a5fa2a50) = ? ERESTARTNOINTR (To be restarted) [pid 18646] --- SIGPROF {si_signo=SIGPROF, si_code=SI_KERNEL} --- [pid 18646] rt_sigreturn() = 56 [pid 18646] clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f96a5fa2a50) = ? ERESTARTNOINTR (To be restarted) [pid 18646] --- SIGPROF {si_signo=SIGPROF, si_code=SI_KERNEL} --- [pid 18646] rt_sigreturn() = 56 [pid 18646] clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f96a5fa2a50) = ? ERESTARTNOINTR (To be restarted) [pid 18646] --- SIGPROF {si_signo=SIGPROF, si_code=SI_KERNEL} --- If i do strace -f on the working process it looks like this: [pid 21442] clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f5f4c1e5a50) = ? ERESTARTNOINTR (To be restarted) [pid 21442] --- SIGPROF {si_signo=SIGPROF, si_code=SI_KERNEL} --- [pid 21442] rt_sigreturn() = 56 [pid 21442] clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f5f4c1e5a50) = ? ERESTARTNOINTR (To be restarted) [pid 21442] --- SIGPROF {si_signo=SIGPROF, si_code=SI_KERNEL} --- [pid 21442] rt_sigreturn() = 56 [pid 21442] clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f5f4c1e5a50) = ? ERESTARTNOINTR (To be restarted) [pid 21442] --- SIGPROF {si_signo=SIGPROF, si_code=SI_KERNEL} --- [pid 21442] rt_sigreturn() = 56 [pid 21442] clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f5f4c1e5a50) = 21448 Process 21448 attached [pid 21448] set_robust_list(0x7f5f4c1e5a60, 24 [pid 21442] write(2, "got pid", 7got pid [pid 21448] <... set_robust_list resumed> ) = 0 [pid 21442] <... write resumed> ) = 7 [pid 21442] write(2, " ", 1 [pid 21448] close(7 If I do not do strace but attach with gdb instead, the bactrace is as follows: (gdb) bt #0 0x00007fa03c9c5025 in __libc_fork () at ../nptl/sysdeps/unix/sysv/linux/x86_64/../fork.c:130 #1 0x00007fa03ccdb155 in __fork () at ../nptl/sysdeps/unix/sysv/linux/pt-fork.c:25 #2 0x00007fa03c36d6eb in posix_fork (self=, noargs=) at ../Modules/posixmodule.c:3832 #3 0x00007fa03c2f2d33 in call_function (oparg=, pp_stack=0x7fffbbc90ae0) at ../Python/ceval.c:4004 #4 PyEval_EvalFrameEx (f=f at entry=0x225e950, throwflag=throwflag at entry=0) at ../Python/ceval.c:2666 #5 0x00007fa03c2f517d in PyEval_EvalCodeEx (co=, globals=, locals=locals at entry=0x0, args=, argcount=argcount at entry=18, kws=0x2693418, kwcount=0, defs=0x0, defcount=0, closure=closure at entry=0x0) at ../Python/ceval.c:3252 #6 0x00007fa03c2f2dd8 in fast_function (nk=, na=18, n=18, pp_stack=0x7fffbbc90d00, func=0x7fa0351e6410) at ../Python/ceval.c:4116 #7 call_function (oparg=, pp_stack=0x7fffbbc90d00) at ../Python/ceval.c:4041 #8 PyEval_EvalFrameEx (f=f at entry=0x2693140, throwflag=throwflag at entry=0) at ../Python/ceval.c:2666 #9 0x00007fa03c2f517d in PyEval_EvalCodeEx (co=, globals=, locals=locals at entry=0x0, args=args at entry=0x7fa0317ee530, argcount=2, kws=kws at entry=0x7fa0317ee578, kwcount=kwcount at entry=1, defs=defs at entry=0x7fa03545bce8, defcount=defcount at entry=13, closure=0x0) at ../Python/ceval.c:3252 #10 0x00007fa03c2f53e5 in function_call.15737 (func=0x7fa0351cff50, arg=0x7fa0317ee518, kw=0x7fa0318247f8) at ../Objects/funcobject.c:526 #11 0x00007fa03c2bce23 in PyObject_Call (func=func at entry=0x7fa0351cff50, arg=arg at entry=0x7fa0317ee518, kw=kw at entry=0x7fa0318247f8) at ../Objects/abstract.c:2529 #12 0x00007fa03c21030d in instancemethod_call.8988 (func=0x7fa0351cff50, arg=0x7fa0317ee518, kw=0x7fa0318247f8) at ../Objects/classobject.c:2602 #13 0x00007fa03c2bce23 in PyObject_Call (func=func at entry=0x7fa035438f00, arg=arg at entry=0x7fa0317e8e50, kw=kw at entry=0x7fa0318247f8) at ../Objects/abstract.c:2529 #14 0x00007fa03c2c148f in slot_tp_init.26761 (self=0x7fa0317f0110, args=0x7fa0317e8e50, kwds=0x7fa0318247f8) at ../Objects/typeobject.c:5692 #15 0x00007fa03c2bf4df in type_call.26491 (type=, args=0x7fa0317e8e50, kwds=0x7fa0318247f8) at ../Objects/typeobject.c:745 #16 0x00007fa03c2bce23 in PyObject_Call (func=func at entry=0x1d7aab0, arg=arg at entry=0x7fa0317e8e50, kw=kw at entry=0x7fa0318247f8) at ../Objects/abstract.c:2529 #17 0x00007fa03c2ef3b1 in ext_do_call (nk=, na=, flags=, pp_stack=0x7fffbbc91300, func=0x1d7aab0) at ../Python/ceval.c:4333 #18 PyEval_EvalFrameEx (f=f at entry=0x7fa0317f2050, throwflag=throwflag at entry=0) at ../Python/ceval.c:2705 #19 0x00007fa03c2f517d in PyEval_EvalCodeEx (co=, globals=, locals=locals at entry=0x0, args=, argcount=argcount at entry=1, kws=0x1da91e0, kwcount=1, defs=0x0, defcount=0, closure=closure at entry=0x0) at ../Python/ceval.c:3252 #20 0x00007fa03c2f2dd8 in fast_function (nk=, na=1, n=3, pp_stack=0x7fffbbc91520, func=0x7fa0351cfcf8) at ../Python/ceval.c:4116 #21 call_function (oparg=, pp_stack=0x7fffbbc91520) at ../Python/ceval.c:4041 #22 PyEval_EvalFrameEx (f=f at entry=0x1da8fc0, throwflag=throwflag at entry=0) at ../Python/ceval.c:2666 #23 0x00007fa03c2f517d in PyEval_EvalCodeEx (co=, globals=, locals=locals at entry=0x0, args=args at entry=0x7fa03ebdd068, argcount=0, kws=kws at entry=0x0, kwcount=kwcount at entry=0, defs=defs at entry=0x0, defcount=defcount at entry=0, closure=0x0) at ../Python/ceval.c:3252 #24 0x00007fa03c2f5310 in function_call.15737 (func=0x7fa0351cf5f0, arg=0x7fa03ebdd050, kw=0x0) at ../Objects/funcobject.c:526 #25 0x00007fa03c2bce23 in PyObject_Call (func=func at entry=0x7fa0351cf5f0, arg=arg at entry=0x7fa03ebdd050, kw=) at ../Objects/abstract.c:2529 #26 0x00007fa03c27b837 in PyEval_CallObjectWithKeywords (func=func at entry=0x7fa0351cf5f0, arg=arg at entry=0x7fa03ebdd050, kw=kw at entry=0x0) at ../Python/ceval.c:3889 #27 0x00007fa03c2feb57 in PyEval_CallFunction (obj=0x7fa0351cf5f0, format=) at ../Python/modsupport.c:557 #28 0x00007fa03e58b94b in dlvhex::PythonPlugin::runPythonMain(std::string) () from /home/ps/_science/projects/hex/installdir_benchmark/lib/libdlvhex2-base.so.11 #29 0x0000000000421eda in main () I am using python 2.7 on ubuntu 14.04. How can I find out why it is hanging? Could it be a bug of the os.fork() implementation? Best Regards, Peter [1] https://github.com/hexhex/core/blob/master/src/PythonPlugin.cpp -- http://www.peterschueller.com/ From quentin.blanchon at multitoll.fr Thu Apr 23 10:28:00 2015 From: quentin.blanchon at multitoll.fr (Quentin Blanchon) Date: Thu, 23 Apr 2015 10:28:00 +0200 Subject: [C++-sig] Compile C++ to python extension Message-ID: Hi, I'm trying to compile C++ class to a python module extension. I found a way here: http://www.boost.org/doc/libs/1_52_0/libs/python/doc/building.html#configuring-boost-build but it doesn't work with versions after boost_1_54, because /tools/build/v2 doesn't exist. I need help to do this with last update and i need some explaination about how to link the needed libraries. Thanks for any help. -------------- next part -------------- An HTML attachment was scrubbed... URL: From stefan at seefeld.name Fri Apr 24 14:50:20 2015 From: stefan at seefeld.name (Stefan Seefeld) Date: Fri, 24 Apr 2015 08:50:20 -0400 Subject: [C++-sig] Compile C++ to python extension In-Reply-To: References: Message-ID: <553A3C0C.3050204@seefeld.name> On 23/04/15 04:28 AM, Quentin Blanchon wrote: > Hi, > I'm trying to compile C++ class to a python module extension. > I found a way > here: http://www.boost.org/doc/libs/1_52_0/libs/python/doc/building.html#configuring-boost-build > > but it doesn't work with versions after boost_1_54, because > /tools/build/v2 doesn't exist. > I need help to do this with last update and i need some explaination > about how to link the needed libraries. Unless you are restricted to a particular version of Boost, I recommend using the latest version. In particular, please always use the version of the documentation corresponding to your version of the library. Then report any discrepancies you find. (For issues with the build system I recommend the Boost mailing list, where many more people hang around that are able to help with Boost.Build issues.) Thanks, Stefan -- ...ich hab' noch einen Koffer in Berlin... From m11hut at gmail.com Tue Apr 28 03:30:49 2015 From: m11hut at gmail.com (Oam) Date: Mon, 27 Apr 2015 18:30:49 -0700 (PDT) Subject: [C++-sig] Boost.Python As Engine's Scripting Language Message-ID: <1430184649015-4674850.post@n4.nabble.com> (Original Message Posted At : http://www.gamedev.net/topic/667952-boostpython-as-engines-scripting-language/ ) Am I thinking about this the right way? I'm currently working with some Boost and Boost.Python in my C++ project, in attempts to get my project's library to utilize Python as it's game scripting language. Similarly I suppose to how Unity utilizes C# as one of it's game scripting languages. So let's say I have an abstract class that contains the virtual methods for overriding the specific behaviors of each particular event, such as Unity's MonoBehavior, but BaseBehavior in my case. This is what I'm trying to do and what I'm thinking the right way to do this is : 1) I have a project that is dedicated to just the library portion of the framework (Contains the BaseBehavior abstract class) class BaseBehavior() { public: virtual void OnUpdate() = 0; }; 2) Export this library portion classes / functions / etc using Boost.Python class BaseBehaviorWrap : public BaseBehavior, public boost::python::wrapper { public: void OnUpdate() { this->get_override("OnUpdate")(); } }; BOOST_PYTHON_MODULE(ModuleName) { boost::python::class_("BaseBehavior") .def("OnUpdate", boost::python::pure_virtual(&BaseBehavior::OnUpdate)); } 3) Within Python, in for example: ObjectBehavior.py I import my library module inheriting from a new class from the BaseBehavior and utilizing the particular override behaviors, such as OnUpdate() import ModuleName class NewObjectBehavior(BaseBehavior): def OnUpdate(self): # Game Behavior # ... 4) Back within the C++ side I'll have a list/vector of all the objects that contain scriptable behavior and their associated attached scripts that contain this BaseBehavior script 5) I'll collect each script per object and call the [ object exec_file(str filename, object globals = object(), object locals = object()) ] function within the Boost.Python on my C++ engine side 6) From here I will utilize the boost::python::extract object to collect my particular overridden functions and call them accordingly per object I'm concerned with my fascination to go back to the C++ side to execute each file and then extract each function I need per object that contains behavior. Is this the right way to do this, or should everything be done on the Python side? I'm really trying to keep the ideal that the GameApp is utilized within C++, such as the window creation, event handling, frame calculations, etc, just the engine specific pieces. While the Python side is dedicated specifically to just Game Behaviors. -- View this message in context: http://boost.2283326.n4.nabble.com/Boost-Python-As-Engine-s-Scripting-Language-tp4674850.html Sent from the Python - c++-sig mailing list archive at Nabble.com. From m11hut at gmail.com Tue Apr 28 08:35:33 2015 From: m11hut at gmail.com (Oam) Date: Mon, 27 Apr 2015 23:35:33 -0700 (PDT) Subject: [C++-sig] Boost.Python As Engine's Scripting Language In-Reply-To: <1430184649015-4674850.post@n4.nabble.com> References: <1430184649015-4674850.post@n4.nabble.com> Message-ID: <1430202933344-4674859.post@n4.nabble.com> After further tinkering I'm feeling like I have a good starting location. I have the BaseBehavior inheritable class exported to the Python side for utilization, and I have my cpp side calling the particular test script that contains a class inheriting from the BaseBehavior and executing it. However, now I am trying to figure out how to collect / extract that particular class after the script has been executed on the cpp side. This is what I'm trying to do as a simple example, but I'm not sure how to specify what the result to look for. All I know is that it inherits from the BaseBehavior class. This is my test.py script: > import Engine > > print("Hello?") > > class TestPiece(MagicEngine.BaseBehavior): > def OnUpdate(self): > print("Hello From TestPiece?") > > test = TestPiece() > test.OnUpdate() This is my cpp side locating the "test" object from the main_namespace BP::dict, which works. > try > { > PyImport_AppendInittab("Engine", &PyInit_Engine); > Py_Initialize(); > > // '__main__' is the name of the scope in which top-level code > executes > BP::object main_module = BP::import("__main__"); > > // we create a dictionary object for the __main__ module's namespace > // m.x = 1 is equivalent to m.__dict__["x"] = 1 > // Special read-only attribute: __dict__ is the modules namespace as a > dictionary object > BP::dict main_namespace = BP::extract > > (main_module.attr("__dict__")); > > auto result = BP::exec_file("../Debug/test.py", main_namespace, > main_namespace); > ME::BaseBehavior& base = BP::extract > < > ME::BaseBehavior& > > > (main_namespace["test"]); > > base.OnUpdate(); > } > catch (...) > { > PyObject *ptype, *pvalue, *ptraceback; > PyErr_Fetch(&ptype, &pvalue, &ptraceback); > > if (pvalue != nullptr) > { > std::string error = BP::extract > > (pvalue); > std::cout << error << std::endl; > } > } How would I make it so it retrieves the TestPiece class for execution without having to manually create an object on the python side. What I really want is for the object to exist on the cpp side, but the python side is what is manipulating it's behavior. -- View this message in context: http://boost.2283326.n4.nabble.com/Boost-Python-As-Engine-s-Scripting-Language-tp4674850p4674859.html Sent from the Python - c++-sig mailing list archive at Nabble.com. From stefan at seefeld.name Tue Apr 28 14:17:00 2015 From: stefan at seefeld.name (Stefan Seefeld) Date: Tue, 28 Apr 2015 08:17:00 -0400 Subject: [C++-sig] Boost.Python As Engine's Scripting Language In-Reply-To: <1430202933344-4674859.post@n4.nabble.com> References: <1430184649015-4674850.post@n4.nabble.com> <1430202933344-4674859.post@n4.nabble.com> Message-ID: <553F7A3C.7070306@seefeld.name> On 28/04/15 02:35 AM, Oam wrote: [...] > How would I make it so it retrieves the TestPiece class for execution > without having to manually create an object on the python side. What I > really want is for the object to exist on the cpp side, but the python > side is what is manipulating it's behavior. The approach I typically use for this is the same in Python and C++: After the script has been run, the "main_namespace" dictionary will contain all the objects (including types) that the script added. Thus it's possible to iterate over all the content and look for types that are derived classes of "MagicEngine.BaseBehavior". Once you have those you may instantiate objects of those types and operate on them in your main application's runtime. In that sense the python script really becomes a configuration file rather than an executable script. Stefan -- ...ich hab' noch einen Koffer in Berlin... From diepen at astron.nl Tue Apr 28 15:07:06 2015 From: diepen at astron.nl (Ger van Diepen) Date: Tue, 28 Apr 2015 15:07:06 +0200 Subject: [C++-sig] Boost.Python As Engine's Scripting Language In-Reply-To: <1430184649015-4674850.post@n4.nabble.com> References: <1430184649015-4674850.post@n4.nabble.com> Message-ID: <553FA21A020000A90002063D@gwsmtp1.astron.nl> I believe we have done something similar to what you intend to do. We have an astronomical query language (implemented in C++) where arbitrary user defined functions (named libname.func) can be loaded dynamically from a shared library. It has the possibility of user defined functions implemented in Python. In the query language such functions are named py.module.func. Each such function has to reside in a class 'func', subclassed from a UDFBase class (basically implemented in C++ and wrapped using Boost-Python). It makes it possible for the Python code to call back to the C++ code (e.g. to get the value of the function arguments). Basically the 'func' class must have a function 'setup' (to check the argument data types, etc.) and a function 'get' to obtain query results. These functions are called from C++ using the boost::object::attr function. Clearly, such functions will perform far from optimal, but it is very convenient for special ad-hoc query functions. If you like to, I can send you more details about the implementation. Cheers, Ger >>> Oam 4/28/2015 3:30 AM >>> (Original Message Posted At : http://www.gamedev.net/topic/667952-boostpython-as-engines-scripting-language/ ) Am I thinking about this the right way? I'm currently working with some Boost and Boost.Python in my C++ project, in attempts to get my project's library to utilize Python as it's game scripting language. Similarly I suppose to how Unity utilizes C# as one of it's game scripting languages. So let's say I have an abstract class that contains the virtual methods for overriding the specific behaviors of each particular event, such as Unity's MonoBehavior, but BaseBehavior in my case. This is what I'm trying to do and what I'm thinking the right way to do this is : 1) I have a project that is dedicated to just the library portion of the framework (Contains the BaseBehavior abstract class) class BaseBehavior() { public: virtual void OnUpdate() = 0; }; 2) Export this library portion classes / functions / etc using Boost.Python class BaseBehaviorWrap : public BaseBehavior, public boost::python::wrapper { public: void OnUpdate() { this->get_override("OnUpdate")(); } }; BOOST_PYTHON_MODULE(ModuleName) { boost::python::class_("BaseBehavior") .def("OnUpdate", boost::python::pure_virtual(&BaseBehavior::OnUpdate)); } 3) Within Python, in for example: ObjectBehavior.py I import my library module inheriting from a new class from the BaseBehavior and utilizing the particular override behaviors, such as OnUpdate() import ModuleName class NewObjectBehavior(BaseBehavior): def OnUpdate(self): # Game Behavior # ... 4) Back within the C++ side I'll have a list/vector of all the objects that contain scriptable behavior and their associated attached scripts that contain this BaseBehavior script 5) I'll collect each script per object and call the [ object exec_file(str filename, object globals = object(), object locals = object()) ] function within the Boost.Python on my C++ engine side 6) From here I will utilize the boost::python::extract object to collect my particular overridden functions and call them accordingly per object I'm concerned with my fascination to go back to the C++ side to execute each file and then extract each function I need per object that contains behavior. Is this the right way to do this, or should everything be done on the Python side? I'm really trying to keep the ideal that the GameApp is utilized within C++, such as the window creation, event handling, frame calculations, etc, just the engine specific pieces. While the Python side is dedicated specifically to just Game Behaviors. -- View this message in context: http://boost.2283326.n4.nabble.com/Boost-Python-As-Engine-s-Scripting-Language-tp4674850.html Sent from the Python - c++-sig mailing list archive at Nabble.com. _______________________________________________ Cplusplus-sig mailing list Cplusplus-sig at python.org https://mail.python.org/mailman/listinfo/cplusplus-sig -------------- next part -------------- An HTML attachment was scrubbed... URL: