Exposing C++ Instances to Python
Hello, I'm in the same bind this topic describes: http://lists.boost.org/boost-users/2009/02/44749.php Unfortunately the subject didn't tell about the resolution or approach he took to succeed. Can anyone help me? Basically: I want to expose a C++ Instance to Python at runtime. I have a pointer to the Instance and need to expose that instance to Python. Thankful for any help, Best regards, ~lwk
AMDG Leonhard Weber wrote:
I'm in the same bind this topic describes: http://lists.boost.org/boost-users/2009/02/44749.php Unfortunately the subject didn't tell about the resolution or approach he took to succeed. Can anyone help me?
Basically: I want to expose a C++ Instance to Python at runtime. I have a pointer to the Instance and need to expose that instance to Python.
Have you tried the Boost.Python documentation? http://www.boost.org/libs/python/ In Christ, Steven Watanabe
Yes, but it seems I'm unable to see the wood for the trees.
The concrete situation:
Im developing a Interface that supposedly is going to enable AIs being
written in Python for a C/C++ environment. What I get is a pointer to a
Callback Instance I have to deliver to the AI dev (Python side). The
Instance enables the AI dev to ask question about the Applications state so
the AI reacts accordingly. Now I have a boost::module wrapper for the Class
Im getting a reference of and successfully built a callback so the embedded
Python is able to fetch the Callback Instance coming from the App. But I run
into...
Sandbox:
// The Callback coming from the Application of which I am not allowed to
taint the Source Tree
struct EngineCallback
{
void setInt(int number) { this->number = number; }
void setLoop(bool loop) { this->loop = loop; }
int getInt() { return this->number; }
bool getLoop() { return this->loop; }
int number;
bool loop;
};
EngineCallback* test = new EngineCallback;
// Entrypoint for Python to come ant fetch the Application Callback
shared_ptr<EngineCallback> PyCallback( EngineCallback* &test ) { return
shared_ptr<EngineCallback>(test); } // The Problem? ...how to convert?
// The Wrapper for all this
BOOST_PYTHON_MODULE(EngineCallback)
{
class_
ends in: Traceback (most recent call last): File "test.py", line 5, in <module> test = PyCallback() Boost.Python.ArgumentError: Python argument types in EngineCallback.PyCallback() did not match C++ signature: PyCallback(EngineCallback* {lvalue})
Conversions in PyCallback missing?, how/with what do I accomplish them?
I think Im having trouble with C/C++ more in general than anything else, but
I would appreciate if you could just point to the things I should look at to
understand and come up with a solution.
Thanks in advance,
lwk
On 25 May 2010 15:40, Steven Watanabe
AMDG
Leonhard Weber wrote:
I'm in the same bind this topic describes: http://lists.boost.org/boost-users/2009/02/44749.php Unfortunately the subject didn't tell about the resolution or approach he took to succeed. Can anyone help me?
Basically: I want to expose a C++ Instance to Python at runtime. I have a pointer to the Instance and need to expose that instance to Python.
Have you tried the Boost.Python documentation? http://www.boost.org/libs/python/
In Christ, Steven Watanabe
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org
AMDG Leonhard Weber wrote:
EngineCallback* test = new EngineCallback;
// Entrypoint for Python to come ant fetch the Application Callback shared_ptr<EngineCallback> PyCallback( EngineCallback* &test ); <snip> # test.py from EngineCallback import PyCallback from EngineCallback import EngineCallback
test = PyCallback()
PyCallback takes one argument. Hence the exception below. Did you intend to use the global "test" instead of taking test as an argument in PyCallback?
Traceback (most recent call last): File "test.py", line 5, in <module> test = PyCallback() Boost.Python.ArgumentError: Python argument types in EngineCallback.PyCallback() did not match C++ signature: PyCallback(EngineCallback* {lvalue})
In Christ, Steven Watanabe
Made a mistake... srry for my lacking knowledge/experience in C++. Trying to improve :D. For test purposes I changed the Python Script so it inits an instance, and then tries to fetch the instance through the PyCallback: ##### from EngineCallback import * a = EngineCallback() b = PyCallback(a)
a
b
#####
On the C++ side I had to change this, its now passing the argument by value
(which I dont want)
shared_ptr<EngineCallback> PyCallback( EngineCallback* test ) { return
shared_ptr<EngineCallback>(test); }
If I passed it per reference EngineCallback* &test (hope Im getting the
jargon right and not mixing up definitions) it would say:
did not match C++ signature:
PyCallback(EngineCallback* {lvalue})
by changing it to pass by value it works, though isnt it making a copy of
the instance? how do I get just a reference to the instance passed to
Python?
On 25 May 2010 16:56, Steven Watanabe
AMDG
Leonhard Weber wrote:
EngineCallback* test = new EngineCallback;
// Entrypoint for Python to come ant fetch the Application Callback shared_ptr<EngineCallback> PyCallback( EngineCallback* &test ); <snip>
# test.py from EngineCallback import PyCallback from EngineCallback import EngineCallback
test = PyCallback()
PyCallback takes one argument. Hence the exception below. Did you intend to use the global "test" instead of taking test as an argument in PyCallback?
Traceback (most recent call last):
File "test.py", line 5, in <module> test = PyCallback() Boost.Python.ArgumentError: Python argument types in EngineCallback.PyCallback() did not match C++ signature: PyCallback(EngineCallback* {lvalue})
In Christ, Steven Watanabe
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
AMDG Leonhard Weber wrote:
Made a mistake... srry for my lacking knowledge/experience in C++. Trying to improve :D.
For test purposes I changed the Python Script so it inits an instance, and then tries to fetch the instance through the PyCallback: ##### from EngineCallback import *
a = EngineCallback() b = PyCallback(a)
a
b
##### On the C++ side I had to change this, its now passing the argument by value (which I dont want) shared_ptr<EngineCallback> PyCallback( EngineCallback* test ) { return shared_ptr<EngineCallback>(test); }
If I passed it per reference EngineCallback* &test (hope Im getting the jargon right and not mixing up definitions) it would say:
did not match C++ signature: PyCallback(EngineCallback* {lvalue})
by changing it to pass by value it works, though isnt it making a copy of the instance? how do I get just a reference to the instance passed to Python?
Since you take a pointer, the pointer will be copied, the object that it points to won't be copied. However, you should probably make the argument a shared_ptr. Otherwise, you'll run into trouble because the new shared_ptr thinks that it has exclusive ownership. In Christ, Steven Watanabe
Are you finding "Boost.Python.register_ptr_to_python" ?
Please look this document
http://www.boost.org/doc/libs/1_41_0/libs/python/doc/v2/register_ptr_to_pyth...
Is this sample same as you require ?
Thanks,
Xiongjia Le ( http://notes.xj-labs.net/ )
On Tue, May 25, 2010 at 11:34 PM, Leonhard Weber
Made a mistake... srry for my lacking knowledge/experience in C++. Trying to improve :D.
For test purposes I changed the Python Script so it inits an instance, and then tries to fetch the instance through the PyCallback: ##### from EngineCallback import *
a = EngineCallback() b = PyCallback(a)
a
b ##### On the C++ side I had to change this, its now passing the argument by value (which I dont want) shared_ptr<EngineCallback> PyCallback( EngineCallback* test ) { return shared_ptr<EngineCallback>(test); }
If I passed it per reference EngineCallback* &test (hope Im getting the jargon right and not mixing up definitions) it would say:
did not match C++ signature: PyCallback(EngineCallback* {lvalue})
by changing it to pass by value it works, though isnt it making a copy of the instance? how do I get just a reference to the instance passed to Python?
On 25 May 2010 16:56, Steven Watanabe
wrote: AMDG
Leonhard Weber wrote:
EngineCallback* test = new EngineCallback;
// Entrypoint for Python to come ant fetch the Application Callback shared_ptr<EngineCallback> PyCallback( EngineCallback* &test ); <snip>
# test.py from EngineCallback import PyCallback from EngineCallback import EngineCallback
test = PyCallback()
PyCallback takes one argument. Hence the exception below. Did you intend to use the global "test" instead of taking test as an argument in PyCallback?
Traceback (most recent call last):
File "test.py", line 5, in <module> test = PyCallback() Boost.Python.ArgumentError: Python argument types in EngineCallback.PyCallback() did not match C++ signature: PyCallback(EngineCallback* {lvalue})
In Christ, Steven Watanabe
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Hi again,
Thank you for your precious help up to now. I figured I had to see more and
take more time working things out by myself before actually making use of
your precious time.
I've spent the last days building a testing environment to simulate the
requirements of the Interface Implementation that is waiting for me.
The Idea:
An Interface that should make communication between the SpringRTS Engine and
Python AI developers possible without tainting the SpringRTS sourcetree, and
encapsulating as much as possible without invading or dictating "how to do
it" on the Python side.
1) Engine starts the Interface (C/C++)
2) Engine tells the Interface to start a AI, passes a Callback that the
Interface has to make accessible for the Python side
3) Interface starts the Python Interpreter and starts the actual AI
4) From Python, through the __init__.py the Client of the Interface fetches
for the Callback instance and also registers some functions that are called
from the Engine on ongoing happening Events (The topic that comes after
finishing the current one which is encapsulating/automating the SAIFloat3 to
and from PyTuple's)
5) The rest is up to the Client and the Engine
For now the Interface is initialized from python.
Here is the Code: (The entire thing is a OpenSource Project, so I don't
really mind on publicly making this an example for other inexperienced users
as myself)
################################## C++ Start
#include
("PythonInterface") .def("exportCallback", &PythonInterface::exportCallback, return_value_policy
()) ;
class_< EngineCallback >("EngineCallback")
.def("setInt", &EngineCallback::setInt)
.def("setLoop", &EngineCallback::setLoop)
.def("getInt", &EngineCallback::getInt)
.def("getLoop", &EngineCallback::getLoop)
// RESPONSIBLE FOR THE COMPILE ERROR
.def("setVec1", &EngineCallback::setVec1)
.def("setVec2", &EngineCallback::setVec2)
.def("getVec1", &EngineCallback::getVec1,
return_value_policy
__main__:2: RuntimeWarning: to-Python converter for SAIFloat3 already registered; second conversion method ignored.
interface = PythonInterface() callback = interface.exportCallback() vec1 = callback.getVec1()
vec1
type(vec1) # Not exactly what I have in mind ################################## Python End
With that Error I don't even get close to testing the actual conversion code
which is an adapted version of
scitbx/boost_python/container_conversions.h. The main modification being,
cutting on the generics and the endless Python
Types checking (reduced to 'is it a tuple?')
To be honest am not experienced enough in C/C++ to see if it works without
actually feeling the pain.
Another thing is the different return_value_policies: by_value,
copy_const_reference(recommendet in the documentation for its efficiency),
reference_existing_object (which gives a reference to the actual object
omitting the desired conversion).
On
Are you finding "Boost.Python.register_ptr_to_python" ? Please look this document http://www.boost.org/doc/libs/1_41_0/libs/python/doc/v2/register_ptr_to_pyth...
Is this sample same as you require ?
Thanks, Xiongjia Le ( http://notes.xj-labs.net/ )
On Tue, May 25, 2010 at 11:34 PM, Leonhard Weber
wrote: Made a mistake... srry for my lacking knowledge/experience in C++. Trying to improve :D.
For test purposes I changed the Python Script so it inits an instance, and then tries to fetch the instance through the PyCallback: ##### from EngineCallback import *
a = EngineCallback() b = PyCallback(a)
a
b ##### On the C++ side I had to change this, its now passing the argument by value (which I dont want) shared_ptr<EngineCallback> PyCallback( EngineCallback* test ) { return shared_ptr<EngineCallback>(test); }
If I passed it per reference EngineCallback* &test (hope Im getting the jargon right and not mixing up definitions) it would say:
did not match C++ signature: PyCallback(EngineCallback* {lvalue})
by changing it to pass by value it works, though isnt it making a copy of the instance? how do I get just a reference to the instance passed to Python?
On 25 May 2010 16:56, Steven Watanabe
wrote: AMDG
Leonhard Weber wrote:
EngineCallback* test = new EngineCallback;
// Entrypoint for Python to come ant fetch the Application Callback shared_ptr<EngineCallback> PyCallback( EngineCallback* &test ); <snip>
# test.py from EngineCallback import PyCallback from EngineCallback import EngineCallback
test = PyCallback()
PyCallback takes one argument. Hence the exception below. Did you intend to use the global "test" instead of taking test as an argument in PyCallback?
Traceback (most recent call last):
File "test.py", line 5, in <module> test = PyCallback() Boost.Python.ArgumentError: Python argument types in EngineCallback.PyCallback() did not match C++ signature: PyCallback(EngineCallback* {lvalue})
In Christ, Steven Watanabe
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
participants (3)
-
Leonhard Weber
-
Steven Watanabe
-
XiongJia Le