Skip to content

Instantly share code, notes, and snippets.

@Liudx1985
Created October 9, 2014 06:05
Show Gist options
  • Save Liudx1985/ed85f5a351a8f8daceb1 to your computer and use it in GitHub Desktop.
Save Liudx1985/ed85f5a351a8f8daceb1 to your computer and use it in GitHub Desktop.
Interactive : c++ & Python
# -*- encoding=UTF-8 -*-
#!/usr/bin/env python
from Hello import *; # import internal c++ module
a = World()
a.set("Liudx")
print("Hello", a.greet())
print(identity(red), identity(color(2)), identity(color.blue))
k = a.t
k.a = 10;
k.b = 3.14;
k.c = "fuck gfw";
k.v[2] = 12;
print(type(k.d), dir(k.d))
k.d.append(1)
k.d.append(2)
k.d.append(3)
k.d.append(4)
print(type(k.e), dir(k.e))
k.e[1] = "a"
k.e[2] = "b"
k.e[3] = "c"
k.e[1] = "~"
k.r = color(4)
print(k.a, k.b, k.c, identity(k.r), k.v[2])
[print(i) for i in k.d]
[print(i) for i in k.e]
k.Reset();
print(len(k.d), len(k.e))
k.setAny(1);
print(type(k.any), dir(k.any))
vvt = vec_T()
vvt.append(k);
k = vvt[0]
print(type(k), k.r)
# namespace example
from example import *; # import internal c++ module ;
f = Foo()
f.vals[0] = 10
f.vals[:] = range(100,103)
[print(i) for i in f.vals]
a_complex = g_vals()
print(type(a_complex ),dir(a_complex [0]))
a_complex [0] += 2 + 2j
print(a_complex[0], a_complex[0].imag, a_complex[0].real)
x = g_goos()
x[0].en = False;
x[0].pe = 0;
print(x[0].en, x[0].pe)
print(x[1].en, x[1].pe)
// Call python code inside C++ while export c++ class & function to PYthon.
// Compile with Python34 installed, the text-code is MBCS.
//
#include <string>
#include <iostream>
#include <fstream>
#include <vector>
#include <map>
#include <complex>
using namespace std;
#include <boost/python.hpp>
#include <boost/any.hpp>
#include <boost/python/dict.hpp>
#include <boost/python/list.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include <boost/python/suite/indexing/map_indexing_suite.hpp>
#include "array_indexing_suite.hpp"
using namespace boost::python;
std::string read_file(std::string const &filepath)
{
std::string output;
std::ifstream file;
file.open(filepath.c_str());
if(file.is_open()){
while(!file.eof()){
std::string line;
std::getline(file,line);
output += line.append("\n");
}
}
file.close();
return output;
}
enum color { red = 1, green = 2, blue = 4 };
color identity_(color x) { return x; }
struct T
{
color _r;
int _a;
float _b;
std::string _c;
std::vector<int> _d;
std::map<int, std::string> _e;
boost::any _any;
int _v[4];
void Reset()
{
_d.clear();
_e.clear();
}
void SetAny(int a){
_any = a;
}
};
inline bool operator == (T const &lhs, T const &rhs) {
return rhs._a == lhs._a &&
rhs. _r == rhs. _r &&
rhs. _a == rhs. _a &&
rhs. _b == rhs. _b &&
rhs. _c == rhs. _c &&
rhs. _d == rhs. _d &&
rhs. _e == rhs. _e;
// && rhs. _any == rhs. _any;
}
struct Foo
{
int vals[3];
boost::array<std::string, 5> strs;
Foo() { std::cout << "Foo()" << std::endl; }
~Foo() { std::cout << "~Foo()" << std::endl; }
};
struct goo
{
bool m_bSendEnable; //发送使能
int m_iSendPeriod; //发送周期
goo() : m_bSendEnable(1), m_iSendPeriod(100){
}
};
inline bool operator==(const goo& lhs, const goo& rhs)
{ return true; }
std::complex<float> g_vals[2];
goo g_goos[2];
BOOST_PYTHON_MODULE(example)
{
namespace python = boost::python;
python::class_<Foo>("Foo")
.add_property("vals", make_array(&Foo::vals))
.add_property("strs", make_array(&Foo::strs))
;
python::class_<goo> ("goo")
.def(init<>())
.def_readwrite("en", &goo::m_bSendEnable)
.def_readwrite("pe", &goo::m_iSendPeriod)
;
python::def("g_vals", make_array(&g_vals));
python::def("g_goos", make_array(&g_goos));
}
//////////////////////////////////////////////////////////////////////////
class World
{
public:
World(){}
void set(std::string msg) { this->msg = msg; }
std::string greet() { return msg; }
std::string msg;
T _t;
};
boost::python::object
any_extract(boost::any const& self)
{
if (self.empty())
return boost::python::object(); // None
if (self.type() == typeid(int)) {
return boost::python::object(*boost::any_cast<int*>(self));
}
if (self.type() == typeid(double)) {
return boost::python::object(*boost::any_cast<double*>(self));
}
throw std::runtime_error("boost::any: unkown value type");
}
// init_module_hello();
BOOST_PYTHON_MODULE(Hello)
{
enum_<color>("color")
.value("red", red)
.value("green", green)
.value("blue", blue)
.export_values()
;
def("identity", identity_);
class_<std::vector<int> >("vec_int")
.def(vector_indexing_suite<std::vector<int> >())
;
class_<std::map<int, std::string> >("map_int_str")
.def(map_indexing_suite<std::map<int, std::string> >())
;
class_<boost::any>("boost_any", no_init)
.def("empty", &boost::any::empty)
.def("extract", any_extract)
;
// Class T;
class_<T> ("T")
.def(init<>())
.def_readwrite("r", &T::_r)
.def_readwrite("a", &T::_a)
.def_readwrite("b", &T::_b)
.def_readwrite("c", &T::_c)
.def_readwrite("d", &T::_d)
.def_readwrite("e", &T::_e)
.def_readwrite("any", &T::_any) // ANY STRUCT
.add_property("v", make_array(&T::_v))
.def("setAny", &T::SetAny)
.def("Reset", &T::Reset);
class_<std::vector<T> >("vec_T")
.def(vector_indexing_suite<std::vector<T> >())
;
class_ <World>("World")
.def(init<>())
.def("greet", &World::greet)
.def("set", &World::set)
.def_readwrite("t", &World::_t);
;
}
//
// # -*- encoding=UTF-8 -*-
// #!/usr/bin/env python _embed.py
// import Hello
// a = Hello.World()
// a.set("Liudx")
// print("Hello", a.greet())
int main(int argc, char *argv[])
{
//!!Now, inside main() and before the call to Py_Initialize()
// we want to call PyImport_AppendInittab( "CppMod", &initCppMod );
// initCppMod is a function created by the BOOST_PYTHON_MODULE macro
// which is used to initialize the Python module CppMod. At this point,
// your embedded python script may call import CppMod and then access
// CppClass as a member of the module.
PyImport_AppendInittab( "Hello", &PyInit_Hello);
PyImport_AppendInittab( "example", &PyInit_example);
Py_Initialize(); // to start the interpreter and create the _main_ module.
string strPath = argv[0];
strPath.resize(strPath.rfind('\\') + 1);
strPath += "_embed.py"; // PY FILE path
try
{
//init_module_Hello();
object _main_ = import("__main__");
object global(_main_.attr("__dict__"));
std::string strFile = read_file(strPath);
object ignored = exec(strFile.c_str(), global, global);
//object ignored = exec_file(strPath.c_str());
object a_world = global["a"];
World &r = extract<World&>(a_world);
World *pWorld = extract<World *>(a_world); // both extract method are OK!
cout << r.greet();
}
catch (error_already_set)
{
PyErr_Print();
}
Py_Finalize();
}
// Call python code.
// Compile with Python31 installed, the text-code is MBCS.
//
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
#include <boost/python.hpp>
#include <boost/python/dict.hpp>
using namespace boost::python;
#define EXEC_STR
std::string read_file(std::string const &filepath)
{
std::string output;
std::ifstream file;
file.open(filepath.c_str());
if(file.is_open()){
while(!file.eof()){
std::string line;
std::getline(file,line);
output += line.append("\n");
}
}
file.close();
return output;
}
int main()
{
#ifdef EXEC_STR
Py_Initialize(); // to start the interpreter and create the _main_ module.
// A simple calculator:
try
{
object main_module = import("__main__");
object main_namespace = main_module.attr("__dict__");
object ignored = exec("print('Hello from python.')", main_namespace); // Python exec(); calc the string in python.
std::string strExp("5**2-(1-6)");
object result = eval(str(strExp.c_str()));
// execution will never get here:
int ret = extract<int>(result);
std::cout << ret << std::endl;
}
catch(error_already_set const &)
{
if (PyErr_ExceptionMatches(PyExc_ZeroDivisionError))
{
// handle ZeroDivisionError specially
}
else
{
// print all other errors to stderr
PyErr_Print();
}
}
Py_Finalize();
#else // exec a file, because exec_file can not work , we just load file and exec string.
/* #"D:/hello.py"
# -*- encoding=UTF-8 -*-
#!/usr/bin/env python
print("hello,world.")
def foo(i = 3):
return i + 2008
class Test:
def __init__(self):
print("init");
pass;
def fun(self):
print("func")
def get():
return Test()
def check(a):
a.fun();
*/
Py_Initialize(); // to start the interpreter and create the _main_ module.
try
{
object _main_ = import("__main__");
object global(_main_.attr("__dict__"));
std::string strFile = read_file("D:/hello.py");
object ignored = exec(strFile.c_str(), global, global);
object foo = global["foo"];
int val = extract<int>(foo(5));
std::cout << "Python has caculated foo as " << val << endl;
object fun_get = global["get"];
object t = fun_get();
object fun_print = global["check"];
fun_print(t);
}
catch(error_already_set){
PyErr_Print();
}
Py_Finalize(); // You should never put this sentence with any ~object.
#endif
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment