[C++-sig] operator in return false while operator == return true
Hi,
Im really scared because I fear a fundamental issue concerning the script
system in my game engine.
In C++, I have a class. In my class I map data to GameObject like:
*class
{
map .
}*
As you see, I use the pointer as key.
When I from c++, in the same class, call a python function I pass the key
like this:
*class::callPythonFunctions()
{
boost::python::get_override("callbackFunction")(boost::python::object(boost::python::ptr(gameobject)));
// the variable gameobj is of type GameObject*
}
*
When I recieve the call in python I do some checks like this:
*def callbackFunction(self, gameobj):
for x in self.mydict.keys():
print("Checking")
print(gameobj == self.mydict)
print(gameobj in self.mydict)*
The above will print something like:
*
Checking
True
False
...*
I do have a overloaded == operator. But how can I fix so that python checks
for my pointer and not the PyObject* pointer ?
// Simon
___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] operator in return false while operator == return true
Hey, sorry for the lacking information.
May I declare it as this instead:
C++ Class
class GameObjectManager
{
map a_map; // this map has "nothing" to do with
python dict
GameObject* createGameObject(id)
{
Gameobject* obj = new Gameobject(id);
a_map[ obj ] = ...some data...
return obj;
}
callPython()
{
// get game object from map
obj = a_map.getgameobject()
boost::python::get_override("callbackFunction")(boost::python::object(boost::python::ptr(obj)));
}
}; // end of class
The python class:
class myRandomClass:
def __init(self, the_c++_GameobjectManager_pointer):
self.manager = the_c++_GameobjectManager_pointer
gameobject = self.manager.createGameObject(1)
#self.manager.createGameObject() returns a pointer to the gameobject created
in c++
self.mylist[gameobject] = ..some data..
def callPython(self, gameobj): # at some point, c++ will call this
function and pass the game object we created above with id 1
for x in self.mylist.keys():
print(x == gameobj) # True
print(gameobj in mylist)# False
So basically the c++ class and python class have their own dict but I want
them to have the *same *address value in their keys .. is it possible??
It seems, in c++ the key is the address of the game object and in Python it
some other address (but they basically point to the same object/memory). Is
there any way around this *without* changing the type of the key being used,
i.e. keep the key as a pointer.
On Fri, Sep 24, 2010 at 4:27 PM, Stefan Seefeld wrote:
> Simon,
>
> I don't quite understand what you are trying to do. Please provide a little
> more detail. Your current mail requires far too much second-guessing to be
> useful.
>
>
> On 09/24/2010 10:08 AM, Simon W wrote:
>
>> Hi,
>>
>> Im really scared because I fear a fundamental issue concerning the script
>> system in my game engine.
>>
>>
>> In C++, I have a class. In my class I map data to GameObject like:
>>
>> *class
>> {
>>map .
>> }*
>>
>
> OK. (Naming this class would help the discussion, though.)
>
>
>> As you see, I use the pointer as key.
>>
>> When I from c++, in the same class, call a python function I pass the key
>> like this:
>>
>> *class::callPythonFunctions()
>> {
>>
>> boost::python::get_override("callbackFunction")(boost::python::object(boost::python::ptr(gameobject)));
>> // the variable /gameobj /is of type GameObject*
>> }
>> *
>>
>
> OK.
>
>
>> When I recieve the call in python I do some checks like this:
>>
>> *def callbackFunction(self, gameobj):
>> for x in self.mydict.keys():
>> print("Checking")
>> print(gameobj == self.mydict)
>> print(gameobj in self.mydict)*
>>
>
> This looks wrong. You iterate over 'x', but don't use it in the loop. May I
> assume that 'mydict' relates to the above map in the
> unnamed class ?
>
>
>>
>> The above will print something like:
>> /
>> Checking
>> True
>> False
>> .../
>>
>
> This suggests that 'gameobj' compares equal to the 'mydict' object, but
> that it is not itself included in the sequence returned by mydict.keys().
>
>
>
>
>> I do have a overloaded == operator. But how can I fix so that python
>> checks for my pointer and not the PyObject* pointer ?
>>
>
> What type do you consider providing an operator== for ?
>
>Stefan
>
>
> --
>
> ...ich hab' noch einen Koffer in Berlin...
>
> ___
> Cplusplus-sig mailing list
> [email protected]
> http://mail.python.org/mailman/listinfo/cplusplus-sig
>
___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig
[C++-sig] TypeError: No to_python (by-value) converter found for C++ type: class std::basic_ostream >
Hi,
Im trying to expose limited parts of std::ostream like this:
{
class_("iosbase", init())
;
class_,
boost::noncopyable>("ios", init())
;
std::ostream&(std::ostream::*write)(const char*,
std::streamsize) = &std::ostream::write;
return class_,
boost::noncopyable>("ostream", no_init)
.def("write", write ,
return_value_policy())
;
}
When I call a python function from a C++ wrapper class:
virtual Uint32serialise(const GameObject* obj, std::ostream&
file)
{
try
{
if(boost::python::override f = get_override("serialise"))
return f(boost::python::object(boost::python::ptr(obj)),
boost::python::object(boost::python::ptr(&file)));
else
return ComponentSystem::serialise(obj, file);
}
catch(...)
{
PyErr_Print();
}
}
I get this error:
*TypeError: No to_python (by-value) converter found for C++ type: class
std::basic_ostream >*
This is the python function
*def serialise(self, gameobj, file):
if(gameobj in self.components):
file.write("HEY", 3)*
What's the problem here? Is is because the ostream argument is an reference?
Thanks!
___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig
[C++-sig] Read and write byte streams python<-->c++
Hey,
I'm trying to serialise some data. I have a c++ class:
class ostream
{
std::ostream& stream;
public:
ostream(std::ostream& s) : stream(s) {}
void write(const char* bytes, Uint32 count)
{
stream.write(bytes, count);
}
};
As you can see, it only wraps std::ostream.
I call the python function like this:
ostream stream(file);
GameObject* obj = new GameObject(...);
if(boost::python::override f = get_override("serialise"))
return f(boost::python::object(boost::python::ptr(obj)),
boost::python::object(boost::python::ptr(&stream)));
Then in the python script:
def serialise(self, gameobj, file):
if(gameobj in self.components):
b = pickle.dumps(self.components[gameobj])
# this is some testing code and dont really make sense because I
don't know what to do...
file.write(str(len(str(b))), 10) # try to serialise an int that
tells the size of the byte-object
print(len(str(b)))
file.write(str(b), len(str(b))) # write the byte object
return len(str(b)) + 10 # return amount of bytes we wrote
First i "pickle" a python object. I convert that byte-object to a string
since my write() function in c++ takes a const char*. But i'd like to pass
the byte-object directly since const char* is basically a byte, right?
Also, the other problem, when im about to read the serialised data I need to
know the size of the previously serialised data to unpickle it. I thoght
that I could to the c++ way and add a integer before the byte stream that
reveal how big it is. But How can i serialise an int from python that takes
up constant "byte-size" for an integer between lets say 0-1!?
Any help on this one? Thanks!
___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] TypeError: No to_python (by-value) converter found for C++ type: class std::basic_ostream >
Thank you for the answer. Is there any way I can prevent it from copying the
stream object even though std::ostream::write() returns a std::ostream& ?
On Wed, Sep 29, 2010 at 11:38 AM, Jakub Zytka wrote:
>
> > I get this error:
> > *TypeError: No to_python (by-value) converter found for C++ type: class
> > std::basic_ostream >*
> >
> > This is the python function
> > *def serialise(self, gameobj, file):
> > if(gameobj in self.components):
> > file.write("HEY", 3)*
> >
> > What's the problem here? Is is because the ostream argument is an
> reference?
> The problem is you are trying to copy a noncopyable object:
>
>
> return class_,
>> boost::noncopyable>("ostream", no_init)
>>
> ostream is noncopyable
>
>
> .def("write", write ,
>> return_value_policy())
>>
> but you define write to return copy (of ostream)
>
> ___
> Cplusplus-sig mailing list
> [email protected]
> http://mail.python.org/mailman/listinfo/cplusplus-sig
>
___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] TypeError: No to_python (by-value) converter found for C++ type: class std::basic_ostream >
I don't quite understand your approach to 100%. But you gave me another
idea. Here's how it looks when I call python function:
Uint32 serialise(const GameObject* obj, std::ostream& file)
{
if(boost::python::override f = get_override("serialise"))
{
// call python function and ask to return a str() of the
pickled bytes
boost::python::str pickled =
f(boost::python::object(boost::python::ptr(obj)));
tuple tup = make_tuple(pickled);
std::string s = extract(tup[0]);
Uint32 size = s.size();
// serialise the size of pickled object
file.write((char*)&size, sizeof(Uint32));
// serialise pickled bytes as string
file.write(s.c_str(), size);
return size + sizeof(Uint32);
}
}
Uint32Python::ComponentSystem::deserialise(std::istream& file,
const GameObject* obj)
{
if(boost::python::override f = get_override("deserialise"))
{
Uint32 size = 0;
// we must know how many bytes to extract
file.read((char*)&size, sizeof(Uint32));
// OK, here starts the conversion, but Im not quite sure how
to do exactly ...
char* sbuf = new char[size];
file.read(sbuf, size);
std::string sdata(sbuf);
boost::python::object data(sdata); // ERROR:
UnicodeDecodeError: 'utf8' codec can't decode bytes in position 80-85:
unsupported Unicode code range
// send the chunk of bytes/string to the deserialise python
function and let it handle the restore of object
f(boost::python::object(boost::python::ptr(obj)), data);
}
return sizeof(Uint32) + size;
}
And the python script:
def serialise(self, gameobj):
if(gameobj in self.components):
return str(pickle.dumps(self.components[gameobj]))
return 0
def deserialise(self, gameobj, data):
pass
On Wed, Sep 29, 2010 at 4:02 PM, Jakub Zytka wrote:
> On 09/29/10 14:11, Simon W wrote:
>
>> Thank you for the answer. Is there any way I can prevent it from copying
>> the
>> stream object even though std::ostream::write() returns a std::ostream& ?
>>
> You can use other return policy, or define one on your own.
>
>
> http://www.boost.org/doc/libs/1_44_0/libs/python/doc/tutorial/doc/html/python/functions.html#python.call_policies
>
> But honestly, I do not think it is the correct way to go. Read below.
>
> > I'm trying to serialise some data. I have a c++ class:
> > class ostream
> > {
> > ...
> > could to the c++ way and add a integer before the byte stream that reveal
> how
> > big it is. But How can i serialise an int from python that takes up
> constant
> > "byte-size" for an integer between lets say 0-1!?
> Everything can be done, but I have a different question:
> I haven't followed all your previous emails, but do you *really* need to
> implement serialization code in python?
> Somehow I feel it is very weird that on one hand you want to have
> serialization code in python, and yet use ostream.
>
> What would be wrong with coding serialization purely in C++, and then
> providing appropriate pickle suite to python:
> struct MyPickleSuite
> {
> // ...
> boost::python::tuple MyPickleSuite::getstate(MyClass & object)
> {
> std::ostringstream oStream(ios_base::binary);
> serialize(oStream, object);
> return boost::python::make_tuple(oStream.str());
> }
>
> void MyPickleSuite::setstate(MyClass & object, boost::python::tuple state)
> {
> // verify tuple correctness etc.
> std::string serializedData = extract(state[0]);
> std::istringstream iStream(serializedData, ios_base::binary);
> serialize(iStream, object); // NOTE: you can use the same code for
> serialization and deserialization. stream type should determine actual
> behavior
> }
> }
>
> That way you do not have to expose ostream to python at all. In fact if you
> wanted to switch to another type of stream (imagine that you have a custom
> stream implementation, which provides eg. type checking) it is cheap. You
> only change a few functions in your pickle suite, nothing more.
>
> Even if you do really need to define serialization in python I see no
> reason to play with streams. I'd rather had a wrapper which hides underlying
> implementation (eg. std::streams) and operates on strings.
>
> Please reconsider your design.
>
> ___
> Cplusplus-sig mailing list
> [email protected]
> http://mail.python.org/mailman/listinfo/cplusplus-sig
>
___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig
[C++-sig] Delete objects, remove from dict
Hey,
I have a dict of the main namespace in boost::python. Now I want to delete
an object from the dict to unload/delete that object
dict namespace = .. extract dict from __main__ module ...;
namespace["test"] = object(555);
namespace.remove("test"); // <- how can I do something like this with boost
python?
// Simon
___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] Delete objects, remove from dict
Hey and thanks for the answer! Unfortunately that doesn't seem to work. I'm
using boost.python for Python 3 ( boost python 1.44? )
error C2039: 'del' : is not a member of 'boost::python::api::object'
I've had a look on the reference manual but I don't understand if it's a
free function or an method of object() ? Neither work ..
The code i'm using:
*object obj = mMainNamespace[ name.c_str() ];
obj.del();*
// Simon
On Mon, Oct 25, 2010 at 1:26 AM, Ralf W. Grosse-Kunstleve wrote:
> > namespace.remove("test"); // <- how can I do something like this with
> boost
> >python?
>
> namespace["test"].del();
>
> See also:
>
> http://www.boost.org/doc/libs/1_44_0/libs/python/doc/v2/object.html
>
> Ralf
> ___
> Cplusplus-sig mailing list
> [email protected]
> http://mail.python.org/mailman/listinfo/cplusplus-sig
>
___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] Delete objects, remove from dict
Thanks that did the trick! On Mon, Oct 25, 2010 at 7:07 PM, Ralf W. Grosse-Kunstleve wrote: > Oh, at second glance... > > > > > > object obj = mMainNamespace[ name.c_str() ]; > > >obj.del(); > > This cannot work! > You need to do it the way I showed before. > > mMainNamespace[ name.c_str() ].del(); > > The [] operator returns a proxy object which supports the del since > it still knows what the target object is. Once you've assigned the > proxy object to boost::python::object the target information is lost. > > Ralf > ___ > Cplusplus-sig mailing list > [email protected] > http://mail.python.org/mailman/listinfo/cplusplus-sig > ___ Cplusplus-sig mailing list [email protected] http://mail.python.org/mailman/listinfo/cplusplus-sig
[C++-sig] Reference count on class object and import()
Hey again,
I'm trying to implement a load / unload module functionallity. When I delete
the module in the __main__ dict the module's reference count is still > 1.
I've been trying to find if I reference it anywhere else in my code but I
can't find anything! When I did a check in vc++ debugger found something.
When I run this code:
object obj = import(name.c_str());
*obj*'s *ob_refcnt* member is 2 when I check in the vc++ debugger. Shouldn't
it be 1?
After that line, I put it in the __main__ dict like:
mMainNamespace[ name.c_str() ] = obj;
The reference count shows 4, as expected.
When I'm entering my unload() function when I want to remove the module I do
like:
void unload()
{
object t = mMainNamespace[ name.c_str() ];
// reference count in t is now 4 ?
mMainNamespace[ name.c_str() ].del(); // I delete but it's not unloaded
properly because it's still referenced somewhere ..
}
What does import() do? It must save some reference somewhere?
___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] Reference count on class object and import()
Of course, I did find another reference that I didn't notice. Python
reference works as expected .. hehe!
On Mon, Oct 25, 2010 at 7:35 PM, Simon W wrote:
> Hey again,
>
> I'm trying to implement a load / unload module functionallity. When I
> delete the module in the __main__ dict the module's reference count is still
> > 1. I've been trying to find if I reference it anywhere else in my code but
> I can't find anything! When I did a check in vc++ debugger found something.
> When I run this code:
>
> object obj = import(name.c_str());
>
> *obj*'s *ob_refcnt* member is 2 when I check in the vc++ debugger.
> Shouldn't it be 1?
>
> After that line, I put it in the __main__ dict like:
>
> mMainNamespace[ name.c_str() ] = obj;
>
> The reference count shows 4, as expected.
>
> When I'm entering my unload() function when I want to remove the module I
> do like:
> void unload()
> {
> object t = mMainNamespace[ name.c_str() ];
> // reference count in t is now 4 ?
>
> mMainNamespace[ name.c_str() ].del(); // I delete but it's not
> unloaded properly because it's still referenced somewhere ..
> }
>
> What does import() do? It must save some reference somewhere?
>
>
___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] Reference count on class object and import()
Alright, it was a couple of days ago since I last had a look on this and it
turns out that issue described in my first mail still persists. Although I
had a typo. Swap 4 with 3 on the reference count. Also, when Im using
PyImport_Import() directly it also shows 2 reference counts?
On Tue, Oct 26, 2010 at 11:29 PM, Simon W wrote:
> Of course, I did find another reference that I didn't notice. Python
> reference works as expected .. hehe!
>
>
> On Mon, Oct 25, 2010 at 7:35 PM, Simon W wrote:
>
>> Hey again,
>>
>> I'm trying to implement a load / unload module functionallity. When I
>> delete the module in the __main__ dict the module's reference count is still
>> > 1. I've been trying to find if I reference it anywhere else in my code but
>> I can't find anything! When I did a check in vc++ debugger found something.
>> When I run this code:
>>
>> object obj = import(name.c_str());
>>
>> *obj*'s *ob_refcnt* member is 2 when I check in the vc++ debugger.
>> Shouldn't it be 1?
>>
>> After that line, I put it in the __main__ dict like:
>>
>> mMainNamespace[ name.c_str() ] = obj;
>>
>> The reference count shows 4, as expected.
>>
>> When I'm entering my unload() function when I want to remove the module I
>> do like:
>> void unload()
>> {
>> object t = mMainNamespace[ name.c_str() ];
>> // reference count in t is now 4 ?
>>
>> mMainNamespace[ name.c_str() ].del(); // I delete but it's not
>> unloaded properly because it's still referenced somewhere ..
>> }
>>
>> What does import() do? It must save some reference somewhere?
>>
>>
>
___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig
[C++-sig] Expose c++ class as python module
Hi, I want to export my c++ class and make an instance of it and then expose it to python as if it were a python module. Is it possible? // export and create instance class_ [...]; namespace["instance"] = ptr( instanceOfMyClass ); Then in python: import instance instance.someFunction() Thank you! /Simon ___ Cplusplus-sig mailing list [email protected] http://mail.python.org/mailman/listinfo/cplusplus-sig
[C++-sig] Wrap std::vector
>From my research it seems not very trivial to wrap std::vector that holds
pointer types. For example:
std::vector
I've looked at boost python vector_index_suite but it just gives me the
runtime error:
> TypeError: No to_python (by-value) converter found for C++ type:
> GameObject*
I have already exposed GameObject:
class_("
GameObject") ...
So it have come to my understanding it's not possible with an out of the box
solution. I have to do some kind of wrapper? Could someone just help me out
where I should start?
Thank you!
___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] Wrap std::vector
I wrap my c++ vector like:
class_("GameObjectList")
.def(vector_index_suite);
When I run the following in python:
objects = gameobject_manager.getGameObjects() # getGameObjects is returning
a std::vector
for object in objects:
...
I get the error
> TypeError: No to_python (by-value) converter found for C++ type:
> GameObject*
I have not tried shared_ptr because I waas hoping on another solution since
it would require a lot of changes to make it a shared_ptr.
On Mon, Aug 1, 2011 at 4:58 PM, diego_pmc wrote:
> You don't really provide that much information: you want help with writing
> a
> wrapper? do you want C++ and Python to point to the same instance of
> `GameObject`? If it's the latter, have you tried doing
> `vector>`?
>
> --
> View this message in context:
> http://boost.2283326.n4.nabble.com/Wrap-std-vector-pointer-tp3708421p3709907.html
> Sent from the Python - c++-sig mailing list archive at Nabble.com.
> ___
> Cplusplus-sig mailing list
> [email protected]
> http://mail.python.org/mailman/listinfo/cplusplus-sig
>
___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig
[C++-sig] Undefined symbols for architecture x86_64 - Building boost 1.52 with Python 3.3 on MacOSX
Hello,
I need som help.
I'm building boost on my Mac OSX 10.8 using the bjam build system.
I have installed Python 3.3 seperatly aas it doesn't ship with the Mac. So
I have my project-config.jam file like:
# Boost.Build Configuration
# Automatically generated by bootstrap.sh
import option ;
import feature ;
if ! darwin in [ feature.values ]
{
using darwin ;
}
project : default-build darwin ;
# Python configuration
using python : 3.3 : /Library/Frameworks/Python.framework/Versions/3.3
: /Library/Frameworks/Python.framework/Versions/3.3/Headers
: /Library/Frameworks/Python.framework/Versions/3.3/lib ;
libraries = --with-python ;
option.set prefix : /usr/local ;
option.set exec-prefix : /usr/local ;
option.set libdir : /usr/local/lib ;
option.set includedir : /usr/local/include ;
# Stop on first error
option.set keep-going : false ;
I'm not used to Mac but I think it compiles but during linking I get the
following error:
Undefined symbols for architecture x86_64:
"_PyInt_AsLong", referenced from:
boost::python::detail::list_base::count(boost::python::api::object
const&) constin list.o
boost::python::detail::list_base::index(boost::python::api::object
const&) constin list.o
boost::python::detail::list_base::insert(boost::python::api::object
const&, boost::python::api::object const&)in list.o
"_PyInt_FromLong", referenced from:
boost::python::detail::returnable::type
boost::python::call(_object*, boost::python::api::object const&, long const&,
boost::type*)in numeric.o
boost::python::detail::returnable::type
boost::python::call(_object*, long
const&, long const&, boost::type*)in numeric.o
boost::python::detail::returnable::type
boost::python::call(_object*,
long const&, long const&, long const&,
boost::type*)in numeric.o
boost::python::detail::returnable::type
boost::python::call(_object*, long
const&, boost::type*)in numeric.o
boost::python::detail::list_base::pop(long)in list.o
boost::python::detail::returnable::type
boost::python::call(_object*, long const&,
boost::python::api::object const&,
boost::type*)in list.o
"_PyString_FromStringAndSize", referenced from:
boost::python::numeric::(anonymous namespace)::load(bool)in numeric.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
What is wrong?
Thanks,
Simon
___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig
[C++-sig] import extension module in python on OSX
Hello,
I've compiled the example code for Boost.Python:
#include
char const* greet()
{
return "hello, world";
}
BOOST_PYTHON_MODULE(hello_ext)
{
using namespace boost::python;
def("greet", greet);
}
It compiles and I got an BoostPythonTest.dylib produced by Xcode. I've
tried to put that file in my site-packages folder and som other places in
order to import it into the interpreter like:
import BoostPythonTest
Traceback (most recent call last):
File "", line 1, in
ImportError: No module named 'BoostPythonTest'
>>>
I've tried to rename it to BoostPythonTest.so and .pyd and so on: But it
doesn't work. What is the proper extension name for boost python modules on
OSX? I'm using boost 1.53, OSX 1.8 and Python 3.2
Thanks in advance,
Simon
___
Cplusplus-sig mailing list
[email protected]
https://mail.python.org/mailman/listinfo/cplusplus-sig
