├── README.md ├── c-call-py-thread ├── c-with-thread.cpp ├── consumer.cpp ├── consumer.py └── run ├── c-call-py ├── consumer.cpp ├── consumer.py ├── py-with-class.cpp ├── py-with-class.py └── run ├── c-python-api.pdf └── py-call-c ├── mypy.cpp ├── mypy.py └── run /README.md: -------------------------------------------------------------------------------- 1 | # c-python 2 | c++ 和python混合编程实例 3 | 各子目录中的run是c++文件编译命令 4 | c++多线程情况很多api需要python3+版本才支持 5 | ## c++调用python相关链接 6 | [C++与Python的混合编程-C++调用Python](https://www.jianshu.com/p/ce26bfc7474f) 7 | [C++ & Python 混合编程(1)-- C++使用Python](https://blog.csdn.net/zizi7/article/details/79098097) 8 | [C/C++与python互相调用](https://blog.csdn.net/u012234115/article/details/50210835) 9 | -------------------------------------------------------------------------------- /c-call-py-thread/c-with-thread.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | int great_function_from_python(char *a) { 8 | cout << a << endl; 9 | int res = 0; 10 | //使用python之前,要调用Py_Initialize();这个函数进行初始化 11 | Py_Initialize(); 12 | if (!Py_IsInitialized()) 13 | { 14 | cout << "Python initialization failed!" << endl; 15 | return 3; 16 | } 17 | //else { 18 | // PyEval_InitThreads(); //开启多线程支持 19 | // int nInit = PyEval_ThreadsInitialized(); //检测线程支持是否开启成功 20 | // if ( nInit ) 21 | // { 22 | // PyEval_SaveThread(); //因为调用PyEval_InitThreads成功后,当前线程就拥有了GIL,释放当前线程的GIL, 23 | // } 24 | //} 25 | //int nHold = PyGILState_Check() ; //检测当前线程是否拥有GIL,python 3+可以用 26 | //PyGILState_STATE gstate; 27 | //if ( !nHold ) 28 | //{ 29 | // gstate = PyGILState_Ensure(); //如果没有GIL,则申请获取GIL 30 | //} 31 | //Py_BEGIN_ALLOW_THREADS; 32 | //Py_BLOCK_THREADS; 33 | 34 | // If my MyPython.py file is in "/Users/xx/code", set the working path to "/Users/xx/code" 35 | // string path = "/Users/xx/code"; 36 | // PySys_SetPath(&path[0u]); 37 | PyRun_SimpleString("import sys"); 38 | PyRun_SimpleString("sys.path.append('./')"); 39 | 40 | PyObject *pModule,*pFunc; 41 | PyObject *pArgs, *pValue; 42 | //这里是要调用的文件名 43 | pModule = PyImport_ImportModule("consumer"); 44 | if (!pModule) // 加载模块失败 45 | { 46 | cout << "[ERROR] Python get module failed." << endl; 47 | return 1; 48 | } 49 | /* build args */ 50 | pArgs = PyTuple_New(1); 51 | PyTuple_SetItem(pArgs,0,PyString_FromString(a)); 52 | //这里是要调用的函数名 53 | pFunc = PyObject_GetAttrString(pModule, "requests_ops"); 54 | if (!pFunc || !PyCallable_Check(pFunc)) // 验证是否加载成功 55 | { 56 | cout << "[ERROR] Can't find funftion " << endl; 57 | return 2; 58 | } 59 | pValue = PyObject_CallObject(pFunc, pArgs); 60 | //PyObject_CallFunction(pFunc, "zhengji"); 61 | //PyObject_CallFunction(pFunc,"s", pArgs); 62 | if (pValue) // 验证是否调用成功 63 | { 64 | res = PyInt_AsLong(pValue); 65 | cout << "result:" << res << endl; 66 | } 67 | //cout << res << endl; 68 | Py_DECREF(pArgs); 69 | Py_DECREF(pFunc); 70 | Py_DECREF(pModule); 71 | 72 | //Py_UNBLOCK_THREADS; 73 | //Py_END_ALLOW_THREADS; 74 | //if (!nHold) 75 | //{ 76 | // PyGILState_Release(gstate); //释放当前线程的GIL 77 | //} 78 | //调用Py_Finalize,这个根Py_Initialize相对应的,必须在python调用完以后执行,否则找不到python module 79 | Py_Finalize(); 80 | return res; 81 | } 82 | int main(int argc, char *argv[]) { 83 | return great_function_from_python("{'a':'b'}"); 84 | } 85 | -------------------------------------------------------------------------------- /c-call-py-thread/consumer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | int great_function_from_python(char *a) { 8 | cout << a << endl; 9 | int res = 0; 10 | int nHold = PyGILState_Check() ; //检测当前线程是否拥有GIL,python 3+可以用 11 | PyGILState_STATE gstate; 12 | if ( !nHold ) 13 | { 14 | gstate = PyGILState_Ensure(); //如果没有GIL,则申请获取GIL 15 | } 16 | Py_BEGIN_ALLOW_THREADS; 17 | Py_BLOCK_THREADS; 18 | 19 | // If my MyPython.py file is in "/Users/xx/code", set the working path to "/Users/xx/code" 20 | // string path = "/Users/xx/code"; 21 | // PySys_SetPath(&path[0u]); 22 | PyRun_SimpleString("import sys"); 23 | PyRun_SimpleString("sys.path.append('./')"); 24 | 25 | PyObject *pModule,*pFunc; 26 | PyObject *pArgs, *pValue; 27 | //这里是要调用的文件名 28 | pModule = PyImport_ImportModule("consumer"); 29 | if (!pModule) // 加载模块失败 30 | { 31 | cout << "[ERROR] Python get module failed." << endl; 32 | return 1; 33 | } 34 | /* build args */ 35 | pArgs = PyTuple_New(1); 36 | //PyTuple_SetItem(pArgs,0,PyString_FromString(a)); 37 | //PyTuple_SetItem(pArgs,0,PyBytes_FromString(a)); 38 | PyTuple_SetItem(pArgs,0,PyUnicode_FromString(a)); 39 | //这里是要调用的函数名 40 | pFunc = PyObject_GetAttrString(pModule, "requests_ops"); 41 | if (!pFunc || !PyCallable_Check(pFunc)) // 验证是否加载成功 42 | { 43 | cout << "[ERROR] Can't find funftion " << endl; 44 | return 2; 45 | } 46 | pValue = PyObject_CallObject(pFunc, pArgs); 47 | //PyObject_CallFunction(pFunc, "zhengji"); 48 | //PyObject_CallFunction(pFunc,"s", pArgs); 49 | if (pValue) // 验证是否调用成功 50 | { 51 | res = PyLong_AsLong(pValue); 52 | cout << "result:" << res << endl; 53 | } 54 | //cout << res << endl; 55 | Py_DECREF(pArgs); 56 | Py_DECREF(pFunc); 57 | Py_DECREF(pModule); 58 | 59 | Py_UNBLOCK_THREADS; 60 | Py_END_ALLOW_THREADS; 61 | if (!nHold) 62 | { 63 | PyGILState_Release(gstate); //释放当前线程的GIL 64 | } 65 | return res; 66 | } 67 | int main(int argc, char *argv[]) { 68 | //使用python之前,要调用Py_Initialize();这个函数进行初始化 69 | Py_Initialize(); 70 | if (!Py_IsInitialized()) 71 | { 72 | cout << "Python initialization failed!" << endl; 73 | return 3; 74 | } 75 | else { 76 | PyEval_InitThreads(); //开启多线程支持 77 | int nInit = PyEval_ThreadsInitialized(); //检测线程支持是否开启成功 78 | if ( nInit ) 79 | { 80 | PyEval_SaveThread(); //因为调用PyEval_InitThreads成功后,当前线程就拥有了GIL,释放当前线程的GIL, 81 | } 82 | } 83 | return great_function_from_python("{'a':'b'}"); 84 | //调用Py_Finalize,这个根Py_Initialize相对应的,必须在python调用完以后执行,否则找不到python module 85 | Py_Finalize(); 86 | } 87 | -------------------------------------------------------------------------------- /c-call-py-thread/consumer.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import threading 3 | import time 4 | def do_task(name): 5 | print(name,"start...") 6 | time.sleep(1) 7 | print(name,"done") 8 | 9 | def requests_ops(msg): 10 | print(msg) 11 | threads = [] 12 | for i in range(10): 13 | thread = threading.Thread(target=do_task, args=(msg,)) 14 | thread.start() 15 | threads.append(thread) 16 | for t in threads: 17 | t.join() 18 | return 0 19 | 20 | -------------------------------------------------------------------------------- /c-call-py-thread/run: -------------------------------------------------------------------------------- 1 | #g++ mypy.cpp -o mypy -lpython2.6 -I /usr/include/python2.6/ 2 | pypath="~/pyenv/versions/3.6.3/" #使用pyenv安装指定版本python的路径(python3.+) 3 | 4 | export LD_LIBRARY_PATH=/usr/local/kafka/lib/:${pypath}lib/:$LD_LIBRARY_PATH 5 | export CPLUS_INCLUDE_PATH=/usr/local/kafka/include/:${pypath}include/python3.6m/:$CPLUS_INCLUDE_PATH 6 | export LIBRARY_PATH=/usr/local/kafka/lib/:${pypath}lib/:$LIBRARY_PATH 7 | 8 | ## -L libdir, -I includepaht, -l libname 9 | g++ consumer.cpp -o consumer -lpython3.6m -lpthread -lutil 10 | #g++ consumer.cpp -o consumer -lpython3.6m -lkafka -lpthread -lutil 11 | #g++ consumer.cpp -o consumer -L ${pypath}lib/ -I ${pypath}include/python3.6m/ -l python3.6m -lkafka -lpthread -lutil 12 | -------------------------------------------------------------------------------- /c-call-py/consumer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | int great_function_from_python(char *a) { 8 | cout << a << endl; 9 | int res = 0; 10 | //使用python之前,要调用Py_Initialize();这个函数进行初始化 11 | Py_Initialize(); 12 | 13 | PyRun_SimpleString("import sys"); 14 | PyRun_SimpleString("sys.path.append('./')"); 15 | 16 | PyObject *pModule,*pFunc; 17 | PyObject *pArgs, *pValue; 18 | //这里是要调用的文件名 19 | pModule = PyImport_ImportModule("consumer"); 20 | /* build args */ 21 | pArgs = PyTuple_New(1); 22 | PyTuple_SetItem(pArgs,0,PyString_FromString(a)); 23 | //这里是要调用的函数名 24 | pFunc = PyObject_GetAttrString(pModule, "requests_ops"); 25 | pValue = PyObject_CallObject(pFunc, pArgs); 26 | //PyObject_CallFunction(pFunc, "s", "zhengji"); 参数说明:pFunc要调用的函数对象, s参数类型(string), 后面是具体参数 27 | //Py_DECREF(pFunc); 28 | 29 | res = PyInt_AsLong(pValue); 30 | //cout << res << endl; 31 | //调用Py_Finalize,这个根Py_Initialize相对应的。 32 | Py_Finalize(); 33 | return res; 34 | } 35 | int main(int argc, char *argv[]) { 36 | return great_function_from_python('{"a":"b"}'); 37 | } 38 | -------------------------------------------------------------------------------- /c-call-py/consumer.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | def requests_ops(msg): 4 | print(msg) 5 | return 0 6 | -------------------------------------------------------------------------------- /c-call-py/py-with-class.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main () { 6 | 7 | //使用python之前,要调用Py_Initialize();这个函数进行初始化 8 | Py_Initialize(); 9 | 10 | PyRun_SimpleString("import sys"); 11 | PyRun_SimpleString("sys.path.append('./')"); 12 | 13 | PyObject * pModule = NULL; 14 | PyObject * pFunc = NULL; 15 | PyObject * pClass = NULL; 16 | PyObject * pInstance = NULL; 17 | PyObject *pArgs, *pValue; 18 | //这里是要调用的文件名 19 | pModule = PyImport_ImportModule("py-with-class"); 20 | //这里是要调用的函数名 21 | pFunc= PyObject_GetAttrString(pModule, "hello"); 22 | //调用函数 23 | PyEval_CallObject(pFunc, NULL); 24 | Py_DECREF(pFunc); 25 | 26 | /* build args */ 27 | pArgs = PyTuple_New(1); 28 | PyTuple_SetItem(pArgs,0, PyString_FromString("asdfasf")); 29 | pFunc = PyObject_GetAttrString(pModule, "world"); 30 | pValue = PyObject_CallObject(pFunc, pArgs); 31 | //PyObject_CallFunction(pFunc, "zhengji"); 32 | //Py_DECREF(pFunc); 33 | 34 | //测试调用python的类 35 | pClass = PyObject_GetAttrString(pModule, "Student"); 36 | if (!pClass) { 37 | printf("Can't find Student class.\n"); 38 | return -1; 39 | } 40 | pInstance = PyInstance_New(pClass, NULL, NULL); 41 | if (!pInstance) { 42 | printf("Can't create Student instance.\n"); 43 | return -1; 44 | } 45 | PyObject_CallMethod(pInstance, "SetName", "s","my family"); 46 | PyObject_CallMethod(pInstance, "PrintName",NULL,NULL); 47 | //调用Py_Finalize,这个根Py_Initialize相对应的,必须在python调用完以后执行,否则找不到python module 48 | Py_Finalize(); 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /c-call-py/py-with-class.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | class Student: 3 | def SetName(self,name): 4 | self._name = name 5 | def PrintName(self): 6 | print self._name 7 | def hello(): 8 | print "Hello World\n" 9 | def world(name): 10 | print name 11 | -------------------------------------------------------------------------------- /c-call-py/run: -------------------------------------------------------------------------------- 1 | g++ mypy.cpp -o mypy -lpython2.6 -I /usr/include/python2.6/ 2 | -------------------------------------------------------------------------------- /c-python-api.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shenghuofei/c-python/e8cea35d9d41f48ecbcb29f6a20142613f749ce9/c-python-api.pdf -------------------------------------------------------------------------------- /py-call-c/mypy.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | extern "C" 4 | void add_func(int a,int b) 5 | { 6 | cout<<"the result: "<