I've exposed a C++ class to Python using Boost Python. The class,
let's say it's called Entity, contains private static data, which is
an array of strings. Though I think it implements it using MFC's
CPtrArray.
I've also exposed a public function from Entity - let's say it's
called foo. This function accesses the private static data (the string
array).
I have multiple instances of Entity stored in a custom C++ container,
which is also exposed to Python as class EntityList.
In Python, I retrive an Entity from the EntityList:
elist = EntityList()
elist.append(Entity())
elist.append(Entity())
entity = elist.get_at(0)
entity.foo()
But it crashes inside foo() as the private static data is empty; or
rather the string array is empty. I know before that point that the
private static data is valid when accessed earlier by the C++ code as
the program works fine. It just won't work from Python, so somehow the
private static data has been blown away but I can't work out where or
why.
The static data is setup at initialisation - my Python code is only
called long after initialisation is complete.
I added a static dump() function to the Entity class that dumps the
string array, and even if I just do the following in Python:
Entity.dump()
in Python, the private static data is empty. Doing the same from C++
works fine. Weird.
I know this is an impossible question to ask, but can anyone think of
something obvious I need to look into?
Thanks 5 1874
>
In Python, I retrive an Entity from the EntityList:
elist = EntityList()
elist.append(Entity())
elist.append(Entity())
entity = elist.get_at(0)
entity.foo()
But it crashes inside foo() as the private static data is empty; or
rather the string array is empty. I know before that point that the
private static data is valid when accessed earlier by the C++ code as
the program works fine. It just won't work from Python, so somehow the
private static data has been blown away but I can't work out where or
why.
Probably it is a problem of lifetime. What is the signature of append?
Who deletes the appended Entity in C++ code?
If append takes a raw pointer, Boost.Python copies the pointer but
destroys the Entity object because it is a temporary and its reference
count went to zero. So the pointer in the list is referring to a
destroyed object, which results in undefined behaviour.
Did you have a look at the lifetime policies of Boost.Python? The
simplest way to workaround the problem is using const reference
arguments, and always use value semantics. If it can result in a
performance penalty, another simple way is using shared_ptr's, which
have their own reference count (different from the one in CPython
lib), but Boost.Python does the magic to make them work together.
HTH,
Giuseppe
Thanks. Maybe it's a DLL boundary issue? I'll look into this too.
On Jul 5, 11:14*pm, Giuseppe Ottaviano <giu...@gmail.comwrote:
In Python, I retrive an Entity from the EntityList:
elist = EntityList()
elist.append(Entity())
elist.append(Entity())
entity = elist.get_at(0)
entity.foo()
But it crashes inside foo() as the private static data is empty; or
rather the string array is empty. I know before that point that the
private static data is valid when accessed earlier by the C++ code as
the program works fine. It just won't work from Python, so somehow the
private static data has been blown away but I can't work out where or
why.
Probably it is a problem of lifetime. What is the signature of append? *
Who deletes the appended Entity in C++ code?
If append takes a raw pointer, Boost.Python copies the pointer but *
destroys the Entity object because it is a temporary and its reference *
count went to zero. So the pointer in the list is referring to a *
destroyed object, which results in undefined behaviour.
Did you have a look at the lifetime policies of Boost.Python? The *
simplest way to workaround the problem is using const reference *
arguments, and always use value semantics. If it can result in a *
performance penalty, another simple way is using shared_ptr's, which *
have their own reference count (different from the one in CPython *
lib), but Boost.Python does the magic to make them work together.
HTH,
Giuseppe
I wonder if it's a DLL boundary problem.
On Jul 5, 11:14*pm, Giuseppe Ottaviano <giu...@gmail.comwrote:
In Python, I retrive an Entity from the EntityList:
elist = EntityList()
elist.append(Entity())
elist.append(Entity())
entity = elist.get_at(0)
entity.foo()
But it crashes inside foo() as the private static data is empty; or
rather the string array is empty. I know before that point that the
private static data is valid when accessed earlier by the C++ code as
the program works fine. It just won't work from Python, so somehow the
private static data has been blown away but I can't work out where or
why.
Probably it is a problem of lifetime. What is the signature of append? *
Who deletes the appended Entity in C++ code?
If append takes a raw pointer, Boost.Python copies the pointer but *
destroys the Entity object because it is a temporary and its reference *
count went to zero. So the pointer in the list is referring to a *
destroyed object, which results in undefined behaviour.
Did you have a look at the lifetime policies of Boost.Python? The *
simplest way to workaround the problem is using const reference *
arguments, and always use value semantics. If it can result in a *
performance penalty, another simple way is using shared_ptr's, which *
have their own reference count (different from the one in CPython *
lib), but Boost.Python does the magic to make them work together.
HTH,
Giuseppe
Could it be a boundary problem? The static data is initialised by the
application. The problem arises when the python module tries to access
it.
On Jul 5, 11:14*pm, Giuseppe Ottaviano <giu...@gmail.comwrote:
In Python, I retrive an Entity from the EntityList:
elist = EntityList()
elist.append(Entity())
elist.append(Entity())
entity = elist.get_at(0)
entity.foo()
But it crashes inside foo() as the private static data is empty; or
rather the string array is empty. I know before that point that the
private static data is valid when accessed earlier by the C++ code as
the program works fine. It just won't work from Python, so somehow the
private static data has been blown away but I can't work out where or
why.
Probably it is a problem of lifetime. What is the signature of append? *
Who deletes the appended Entity in C++ code?
If append takes a raw pointer, Boost.Python copies the pointer but *
destroys the Entity object because it is a temporary and its reference *
count went to zero. So the pointer in the list is referring to a *
destroyed object, which results in undefined behaviour.
Did you have a look at the lifetime policies of Boost.Python? The *
simplest way to workaround the problem is using const reference *
arguments, and always use value semantics. If it can result in a *
performance penalty, another simple way is using shared_ptr's, which *
have their own reference count (different from the one in CPython *
lib), but Boost.Python does the magic to make them work together.
HTH,
Giuseppe
Oops - I didn't see my post so I thought something had gone wrong and
reposted. Apologies for the multiple posts.
On Jul 9, 11:57*am, Stodge <sto...@gmail.comwrote:
Could it be a boundary problem? The static data is initialised by the
application. The problem arises when the python module tries to access
it.
On Jul 5, 11:14*pm, Giuseppe Ottaviano <giu...@gmail.comwrote:
In Python, I retrive an Entity from the EntityList:
elist = EntityList()
elist.append(Entity())
elist.append(Entity())
entity = elist.get_at(0)
entity.foo()
But it crashes inside foo() as the private static data is empty; or
rather the string array is empty. I know before that point that the
private static data is valid when accessed earlier by the C++ code as
the program works fine. It just won't work from Python, so somehow the
private static data has been blown away but I can't work out where or
why.
Probably it is a problem of lifetime. What is the signature of append? *
Who deletes the appended Entity in C++ code?
If append takes a raw pointer, Boost.Python copies the pointer but *
destroys the Entity object because it is a temporary and its reference *
count went to zero. So the pointer in the list is referring to a *
destroyed object, which results in undefined behaviour.
Did you have a look at the lifetime policies of Boost.Python? The *
simplest way to workaround the problem is using const reference *
arguments, and always use value semantics. If it can result in a *
performance penalty, another simple way is using shared_ptr's, which *
have their own reference count (different from the one in CPython *
lib), but Boost.Python does the magic to make them work together.
HTH,
Giuseppe
This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Li Daobing |
last post by:
I can't use .def(str(self))
I write a simple example, without `str', I can build it well, but with
this one, I can't build
//Rational.cpp
#include <boost/python.hpp>
#include <iostream>
...
|
by: cesco |
last post by:
Hi,
I'm using the boost library program_options for parsing the command
line given to my program as described in the class Parameter:
// Main.cpp
#include "Parameter.h"
using namespace std;...
|
by: Pedro |
last post by:
Hello pythonians! ;-D ,
I have a little problem when I expose (assisted by boost.python) classes
with virtual functions, specially with operator().
In the C++ code below I test two different...
|
by: mystilleef |
last post by:
Hello,
What is the Pythonic way of implementing getters and setters. I've
heard
people say the use of accessors is not Pythonic. But why? And what is
the alternative? I refrain from using them...
|
by: Stou Sandalski |
last post by:
Hi,
I have a python library created by wrapping the C++ library using
Boost.Python, the problem is that the wrappers are not very
pythonic.... so I want to add some methods that do not exist in...
|
by: mkvenkit.vc |
last post by:
Hello,
I hope this is the right place to post a question on Boost. If not,
please let me know where I can post this message and I will do so.
I am having a strange problem with std::string as...
|
by: Sh4wn |
last post by:
Hi,
first, python is one of my fav languages, and i'll definitely keep
developing with it. But, there's 1 one thing what I -really- miss:
data hiding. I know member vars are private when you...
|
by: Kemmylinns12 |
last post by:
Blockchain technology has emerged as a transformative force in the business world, offering unprecedented opportunities for innovation and efficiency. While initially associated with cryptocurrencies...
|
by: Naresh1 |
last post by:
What is WebLogic Admin Training?
WebLogic Admin Training is a specialized program designed to equip individuals with the skills and knowledge required to effectively administer and manage Oracle...
|
by: Arjunsri |
last post by:
I have a Redshift database that I need to use as an import data source. I have configured the DSN connection using the server, port, database, and credentials and received a successful connection...
|
by: Oralloy |
last post by:
Hello Folks,
I am trying to hook up a CPU which I designed using SystemC to I/O pins on an FPGA.
My problem (spelled failure) is with the synthesis of my design into a bitstream, not the C++...
|
by: Carina712 |
last post by:
Setting background colors for Excel documents can help to improve the visual appeal of the document and make it easier to read and understand. Background colors can be used to highlight important...
|
by: Rahul1995seven |
last post by:
Introduction:
In the realm of programming languages, Python has emerged as a powerhouse. With its simplicity, versatility, and robustness, Python has gained popularity among beginners and experts...
|
by: Ricardo de Mila |
last post by:
Dear people, good afternoon...
I have a form in msAccess with lots of controls and a specific routine must be triggered if the mouse_down event happens in any control.
Than I need to discover what...
|
by: Johno34 |
last post by:
I have this click event on my form. It speaks to a Datasheet Subform
Private Sub Command260_Click()
Dim r As DAO.Recordset
Set r = Form_frmABCD.Form.RecordsetClone
r.MoveFirst
Do
If...
|
by: ezappsrUS |
last post by:
Hi,
I wonder if someone knows where I am going wrong below. I have a continuous form and two labels where only one would be visible depending on the checkbox being checked or not. Below is the...
| |