Sign In | Register Now About Bytes | Help | Site Map
Connecting Tech Pros Worldwide

Boost Python - C++ class' private static data blown away beforeaccessing in Python?

Question posted by: Stodge (Guest) on July 4th, 2008 04:25 PM
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
Giuseppe Ottaviano's Avatar
Giuseppe Ottaviano
Guest
n/a Posts
July 6th, 2008
03:25 AM
#2

Re: Boost Python - C++ class' private static data blown away beforeaccessing in Python?
>
Quote:
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

Stodge's Avatar
Stodge
Guest
n/a Posts
July 9th, 2008
03:45 PM
#3

Re: Boost Python - C++ class' private static data blown away beforeaccessing in Python?
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:
Quote:
Quote:
In Python, I retrive an Entity from the EntityList:

>
Quote:
elist = EntityList()
elist.append(Entity())
elist.append(Entity())

>
Quote:
entity = elist.get_at(0)

>
Quote:
entity.foo()

>
Quote:
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



Stodge's Avatar
Stodge
Guest
n/a Posts
July 9th, 2008
03:45 PM
#4

Re: Boost Python - C++ class' private static data blown away beforeaccessing in Python?
I wonder if it's a DLL boundary problem.

On Jul 5, 11:14*pm, Giuseppe Ottaviano <giu...@gmail.comwrote:
Quote:
Quote:
In Python, I retrive an Entity from the EntityList:

>
Quote:
elist = EntityList()
elist.append(Entity())
elist.append(Entity())

>
Quote:
entity = elist.get_at(0)

>
Quote:
entity.foo()

>
Quote:
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



Stodge's Avatar
Stodge
Guest
n/a Posts
July 9th, 2008
04:05 PM
#5

Re: Boost Python - C++ class' private static data blown away beforeaccessing in Python?
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:
Quote:
Quote:
In Python, I retrive an Entity from the EntityList:

>
Quote:
elist = EntityList()
elist.append(Entity())
elist.append(Entity())

>
Quote:
entity = elist.get_at(0)

>
Quote:
entity.foo()

>
Quote:
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



Stodge's Avatar
Stodge
Guest
n/a Posts
July 9th, 2008
06:55 PM
#6

Re: Boost Python - C++ class' private static data blown away beforeaccessing in Python?
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:
Quote:
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:
>
Quote:
Quote:
In Python, I retrive an Entity from the EntityList:

>
Quote:
Quote:
elist = EntityList()
elist.append(Entity())
elist.append(Entity())

>
Quote:
Quote:
entity = elist.get_at(0)

>
Quote:
Quote:
entity.foo()

>
Quote:
Quote:
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.

>
Quote:
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.

>
Quote:
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.

>
Quote:
HTH,
Giuseppe



 
Not the answer you were looking for? Post your question . . .
189,798 Experts ready to help you find a solution.
Sign up for a free account, or Login (if you're already a member).

Latest Articles: Read & Comment
  • Didn't find the answer you were looking for?
    Post Your Question
  • Top Community Contributors