My app have some events, each event can have some actions. These actions is implemented in C++. I want to expose those core functions to python and use python to write the action. The advantage is I can modify actions without recompile. For example:
CppClass o;
// --- this is a action----
o.f1();
o.f2();
// ------------------------
use python to script the action:
def action1(o):
o.f1()
o.f2()
In c++, use interpreter to run this script, find action1 and call it with a PyObject which convert from c++ object. Actually, I have not expose f1() & f2() to python, I just use python to regroup the definition of action, all function is running by c++ binary code. Notice that I have not to give a definition of f1() & f2() in python.
The problem is: how I expose global functions? such as:
def action2():
gf1()
gf2()
boost::python can expose function, but it is different, it need compile a DLL file and the main() is belong to python script. Of course I can make global functions to be a class static member, but I just want to know. Notice that I HAVE TO give a definition of gf1() & gf2() in python.
Jython can do this easily: just import Xxx in python code and call Xxx.gf1() is ok. But in cython, how I define gf1() in python? This is a kind of extension, but extension requires Xxx be compiled ahead. It seems only way is make gf() into a class?
Solved. boost::python's doc is really poor...
For example: expose function
void ff(int x, int y)
{
std::cout<<x<<" "<<y<<std::endl;
}
to python:
import hello
def foo(x, y)
hello.ff(x, y)
you need to expose it as a module:
BOOST_PYTHON_MODULE(hello)
{
boost::python::def("ff", ff, boost::python::arg("x"), boost::python::arg("y"));
}
But this still is not a 'global function', so expose it to python's main scope:
BOOST_PYTHON_MODULE(__main__)
{
boost::python::def("ff", ff, boost::python::arg("x"), boost::python::arg("y"));
}
then you can write:
def foo(x, y)
ff(x, y)
You might also want to have a look at Cython.
Cython's main function is to translate (a subset of) Python code to C
or C++ code to build native code Python extensions. As a consequence,
it allows interfacing C/C++ code with a very terse and Python-ish
syntax.
Cython's user guide provides a
good example of how to call a simple C++ class from Python:
http://docs.cython.org/src/userguide/wrapping_CPlusPlus.html#declaring-a-c-class-interface
In addition to creating extensions, Cython can also generate C/C++
code that embeds the Python interpreter, so you do not need to build
and ship an external DLL. See details at: http://wiki.cython.org/EmbeddingCython
ffpython is c++ lib that wrap python 2.x api. see code repo
call python function: ffpython.call("fftest", "test_stl", a1, a2, a3);
reg c++ class:
ffpython.reg_class<foo_t, PYCTOR(int)>("foo_t")
.reg(&foo_t::get_value, "get_value")
.reg(&foo_t::set_value, "set_value")
.reg(&foo_t::test_stl, "test_stl")
.reg_property(&foo_t::m_value, "m_value");
Related
I'm using boost python to bind c++ and python.
I want to make custom data type in run time.
For example this is excel file which include my new custom type infos.
Rectangle.xls
And i will read this excel file first and make new Rectangle type.
And i want to add this custom type to with c++ boost python in run time.
In c++ side, BOOST_PYTHON_MODULE macro will make functions.
BOOST_PYTHON_MODULE(HelloModule)
{
python::class_<Temp> temp;
temp.def(init<int>());
}
And i can bind like this.
PyImport_AppendInittab("HelloModule", &initHelloModule);
Boost python will bind this at run time but it can not edit at run time.
It can edit only when the coding time.
Is there have any boost python interface or way to make or import custom type in runtime?
I'm using boost::python to do a hybrid C++/python application: the C++ app calls a collection of python scripts, which in turn use the C++ program's functions, classes, etc., exposed as python objects. (Python 2.x.)
BOOST_PYTHON_MODULE(MyModule) exposes the C++ to python as expected.
My initialization code:
Py_Initialize();
initMyModule(); // import MyModule
namespace bpl = boost::python;
Now I want my C++ code to get at MyModule, too. In python, you just write globals()['MyModule']. But this (and things like it) don't work in C++:
bpl::object globals = bpl::eval("globals()");
This fails at run-time with
File "<string>", line 1, in <module>; NameError: name 'globals' is not defined
As an aside, I see many examples of setting up __main__ like this:
bpl::object m = bpl::import("__main__");
bpl::dict g = m.attr("__dict__"); // like locals(), but not globals()
This doesn't fail, and gives locals, but according to the Py_Initialize docs, __main__ is already set up. And it doesn't let you see globals, where you'd find your imported module.
You don't need the explicit bpl::import("__main__");.
Here are the globals:
bpl::dict globals()
{
bpl::handle<> mainH(bpl::borrowed(PyImport_GetModuleDict()));
return bpl::extract<bpl::dict>(bpl::object(mainH));
}
Since everything is managed by smart pointers, returning and manipulating bpl::dict directly works fine.
bpl::object myMod = globals()["MyModule"];
globals()["myNewGlobal"] = 88;
I have a Lua script that uses some functions of my C++ application.
I use this script with 2 different C++ application, and I would like to be able to protect a call for not being bound through tolua.
For example:
- Let's say that I have two C++ applications: MyApp1 and MyApp2
- I made a wrapper of MyApp1 with tolua++ and I call one of its functions like this in a Lua script:
MyApp1:MyFunc()
Now I use this same script with MyApp2, that doesn't have any tolua++ binding of this type.
And I then get an error of this type:
[string "MyApp2.lua"]:157: attempt to index global 'MyApp1' (a nil value)
So I would like Lua not to send me an error when calling this method.
I tried to use:
pcall( MyApp1:MyFunc() )
But the script keeps on crashing on this line.
if MyApp1 then
MyApp1:MyFunc()
end
if MyApp1 then
MyApp1:MyFunc()
end
Above will work, but isn't it cleaner to separate application dependent and independent scripts? That way you woudn't have to worry about it.
I want to pass callback from my python code to c++
I want my code look something like this:
In C++ :
typedef void (*MyCallback_t) (CallbackInfo);
class MyClass
{...
void setcallback(MyCallback_t cb);
...
}
And to use it in python :
import mylib
def myCallback(mylib_CallbackInfo):
...
t = mylib.MyClass()
t.setcallback(myCallback)
I saw some topics near my problem but couldn't solve it
For example here :
Realtime processing and callbacks with Python and C++ there is advice to use boost::python and warning about GLI but no examples.
And here
How to call a python function from a foreign language thread (C++) there is no full description with python code part and with "BOOST_PYTHON_MODULE" part
I also found link to use py_boost_function.hpp for example in Boost python howto but it didn't compile and actualy I couldn't understand how to use it.
Ok, I'm still trying to figure this out too, but here's whats working for me so far:
#this is the variable that will hold a reference to the python function
PyObject *py_callback;
#the following function will invoked from python to populate the call back reference
PyObject *set_py_callback(PyObject *callable)
{
py_callback = callable; /* Remember new callback */
return Py_None;
}
...
#Initialize and acquire the global interpreter lock
PyEval_InitThreads();
#Ensure that the current thread is ready to call the Python C API
PyGILState_STATE state = PyGILState_Ensure();
#invoke the python function
boost::python::call<void>(py_callback);
#release the global interpreter lock so other threads can resume execution
PyGILState_Release(state);
The python function is invoked from C++, and executes as expected.
These test files from the boost::python source code repository contains great examples about how to pass callbacks from Python into C++:
https://github.com/boostorg/python/blob/develop/test/callbacks.cpp
https://github.com/boostorg/python/blob/develop/test/callbacks.py
What I am trying to do is that I want to read a file using python, and then with the data in the file, create a variable in c/c++(I don't want to read var from the file :) ).
Is this possible?
If this is possible, then how would you do it?
Thank you guys!
Maybe Boost.Python can help.
You could expose a C++ function to your Python script. Something like that:
void do_sth_with_processed_data(const std::string& data)
{
// …
}
BOOST_PYTHON_MODULE(do_sth)
{
def("do_sth_with_processed_data", do_sth_with_processed_data);
}
In your Python script you now could have:
import do_sth
// …
do_sth_with_processed_data(my_processed_data) // this calls the c++ function
Yes. Open the first file in Python, process it and save the results to a second file.
Then open the second file in your C or C++ program and use the data.
Swig can generate a Python interface to C or C++ code for you automatically. Since it wraps constructors you could read the data in Python and then pass it (with a little care) to the constructor of a C++ class for example.