Created
October 9, 2014 06:05
-
-
Save Liudx1985/ed85f5a351a8f8daceb1 to your computer and use it in GitHub Desktop.
Interactive : c++ & Python
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- 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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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