C/C++与Python互相调用

来源:互联网 发布:蓝盾 大数据 编辑:程序博客网 时间:2024/05/19 19:33

一、【C/C++调用Python】

参考:http://www.open-open.com/lib/view/open1329532219656.html

1、例程:

test.c

#include "Python.h"void HelloWorld(){     Py_Initialize();        PyRun_SimpleString("import sys");         PyRun_SimpleString("print 'hi,python!'");        PyRun_SimpleString("sys.path.append('./')");     PyObject * pModule = NULL;     PyObject * pFunc = NULL;     printf("11111 %x\n",pModule);     pModule =PyImport_ImportModule("mypy");        printf("11111 %x\n",pModule);     pFunc= PyObject_GetAttrString(pModule, "HelloWorld");     PyEval_CallObject(pFunc, NULL);     Py_Finalize();}void main(){        printf("tttttt\n");        HelloWorld();}

mypy.py

#!/usr/bin/env pythonprint '2222'def HelloWorld():  print 'this is Helloworld'

编译: mips-linux-gnu-gcc -EL test.c -L./lib -lpython2.7 -I./include/python2.7/

2、例程:

test.cpp

#include <iostream>  #include "Python.h"   using namespace std;     void HelloWorld();  void Add();  void TestTransferDict();  void TestClass();     int main()  {       cout << "Starting Test..." << endl;          cout << "HelloWorld()-------------" << endl;       HelloWorld();       cout << "Add()--------------------" << endl;       Add();       cout << "TestDict-----------------" << endl;       TestTransferDict();       cout << "TestClass----------------" << endl;       TestClass();     //     system("pause");       return 0;  }     void HelloWorld()  {       Py_Initialize();        PyRun_SimpleString("import sys");         PyRun_SimpleString("print 'hi,python!'");        PyRun_SimpleString("sys.path.append('./')");     PyObject * pModule = NULL;     PyObject * pFunc = NULL;     pModule =PyImport_ImportModule("Test001");     pFunc= PyObject_GetAttrString(pModule, "HelloWorld");     PyEval_CallObject(pFunc, NULL);     Py_Finalize();}      void Add()  {       Py_Initialize();          PyRun_SimpleString("import sys");         PyRun_SimpleString("sys.path.append('./')");        PyObject * pModule = NULL;           PyObject * pFunc = NULL;             pModule =PyImport_ImportModule("Test001");     pFunc= PyObject_GetAttrString(pModule,"add");     PyObject *pArgs = PyTuple_New(2);     PyTuple_SetItem(pArgs, 0, Py_BuildValue("i", 5));     PyTuple_SetItem(pArgs, 1, Py_BuildValue("i", 7));     PyObject *pReturn = NULL;       pReturn = PyEval_CallObject(pFunc, pArgs);     int result;       PyArg_Parse(pReturn, "i", &result);     cout << "5+7 = " << result << endl;          Py_Finalize();                  }     void TestTransferDict()  {       Py_Initialize();          PyRun_SimpleString("import sys");        PyRun_SimpleString("sys.path.append('./')");     PyObject * pModule = NULL;           PyObject * pFunc = NULL;             pModule =PyImport_ImportModule("Test001");     pFunc= PyObject_GetAttrString(pModule, "TestDict");     PyObject *pArgs = PyTuple_New(1);        PyObject *pDict = PyDict_New();     PyDict_SetItemString(pDict, "Name", Py_BuildValue("s", "WangYao"));     PyDict_SetItemString(pDict, "Age", Py_BuildValue("i", 25));     PyTuple_SetItem(pArgs, 0, pDict);     PyObject *pReturn = NULL;       pReturn = PyEval_CallObject(pFunc, pArgs);     int size = PyDict_Size(pReturn);       cout <<"TTTTTTTT" << size << endl;       PyObject *pNewAge = PyDict_GetItemString(pReturn, "Age");       int newAge;       PyArg_Parse(pNewAge, "i", &newAge);       cout << "True Age: " << newAge << endl;              Py_Finalize();                  }     void TestClass()  {       Py_Initialize();          PyRun_SimpleString("import sys");        PyRun_SimpleString("sys.path.append('./')");     PyObject * pModule = NULL;           PyObject * pFunc = NULL;             pModule =PyImport_ImportModule("Test001");     pFunc= PyObject_GetAttrString(pModule, "TestDict");      PyObject *pClassPerson = PyObject_GetAttrString(pModule, "Person");       PyObject *pInstancePerson = PyInstance_New(pClassPerson, NULL, NULL);       PyObject_CallMethod(pInstancePerson, "greet", "s", "Hello Kitty");        Py_Finalize();            }

Test001.py

def HelloWorld():      print "Hello World"  def add(a, b):      return a+b  def TestDict(dict):      print dict      dict["Age"] = 17      return dict  class Person:      def greet(self, greetStr):          print greetStr  #print add(5,7)  #a = raw_input("Enter To Continue...")

3、

其中

        PyRun_SimpleString("import sys");        PyRun_SimpleString("sys.path.append('./')");

分别导入sys,接着设置py文件的路径


4、PySys_SetArgv、PySys_SetPath和PyRun_AnyFile的用法:

test1.c

#include "Python.h"void HelloWorld(){        char *argv[2];        unsigned int argc;        argc = 2;        char *tmp="hello";        char *tmp1="world";        argv[0]= tmp;        argv[1]= tmp1;        Py_Initialize();        PySys_SetArgv(argc, argv);        PySys_SetPath("./");//      PyRun_SimpleString("import sys"); //      PyRun_SimpleString("sys.path.append('./')");        PyRun_SimpleString("print 'hi,python!'");        PyObject * pModule = NULL;        PyObject * pFunc = NULL;        pModule =PyImport_ImportModule("mypy");        Py_Finalize();}void main(){        printf("tttttt\n");        HelloWorld();}

mypy.py

#!/usr/bin/env pythonimport sysprint '----sys.argv[0]: ',sys.argv[0]print '----sys.argv[1]: ',sys.argv[1]print '2222'def HelloWorld():  print 'this is Helloworld'if __name__ == '__main__':  print 'this is main

PySys_SetArgv,设置参数;

PySys_SetPath,设置py文件路径;如果要设置多个路径,在linux环境下可以用冒号:隔开,如:

PySys_SetPath("./:/usr/lib/python2.7:/usr/lib/python2.7/lib-dynload");

如果用下面的代码:

      PyObject* file = PyFile_FromString((char *) "mypy.py", (char*)"r");      FILE *fp = PyFile_AsFile(file);      PyRun_AnyFile(fp,"mypy.py");

来代替:

        PyObject * pModule = NULL;        pModule =PyImport_ImportModule("mypy");

也可以执行mypy.py,但是PyRun_AnyFile会执行mypy.py中的__main__中的代码;

有关run file的其他类似操作请参照:http://docs.python.org/2/c-api/veryhigh.html


二、【Python调用C/C++】

 Python开发效率高,运行效率低。而c/c++恰恰相反。因此在python脚本中调用c/c++的库,对python进行扩展,是很有必要的。使用python api,http://www.python.org/doc/ 

1、

参考:http://www.oschina.net/question/234345_48628

test.c

#include <stdio.h>void display() {printf("This is Display Function\n"); }

gcc -shared -fpic test.c -o libtestso1.so -I./include/python2.7

test.py

import ctypesso = ctypes.CDLL("./libtestso1.so")so.display()

2、

testso2.cpp

#include<iostream>class TestLib{        public:                void display();                void display(int a);};void TestLib::display() {       std::cout<<"First display"<<std::endl;}void TestLib::display(int a) {        std::cout<<"Second display"<<std::endl;}extern "C" {        TestLib obj;        void display() {               obj.display();         }        void display_int() {               obj.display(2);         }}

g++ -shared -fpic testso2.cpp -o libtestso2.so -I./include/python2.7/

testso2.py

import ctypesso = ctypes.CDLL("./libtestso2.so")so.display()so.display_int(1)


3、

参考:http://blog.csdn.net/marising/article/details/2845339

testso.cpp

#include <python2.6/Python.h> //包含python的头文件  // 1 c/cpp中的函数  int my_c_function(const char *arg) {    int n = system(arg);    return n;  }  // 2 python 包装  static PyObject * wrap_my_c_fun(PyObject *self, PyObject *args) {    const char * command;    int n;    if (!PyArg_ParseTuple(args, "s", &command))//这句是把python的变量args转换成c的变量command      return NULL;    n = my_c_function(command);//调用c的函数    return Py_BuildValue("i", n);//把c的返回值n转换成python的对象  }  // 3 方法列表  static PyMethodDef MyCppMethods[] = {      //MyCppFun1是python中注册的函数名,wrap_my_c_fun是函数指针      { "MyCppFun1", wrap_my_c_fun, METH_VARARGS, "Execute a shell command." },      { NULL, NULL, 0, NULL }  };  int getTestInt(){        return 10;}// 4 模块初始化方法  PyMODINIT_FUNC initMyCppModule(void) {    //初始模块,把MyCppMethods初始到MyCppModule中    PyObject *m = Py_InitModule("MyCppModule", MyCppMethods);    if (m == NULL)      return;         PyModule_AddStringConstant(m, (char*)"testString", (char*)"this is test string");        PyModule_AddIntConstant(m,"testInt",getTestInt());  }  

也可以使用PyArg_ParseTupleAndKeywords()来对参数进行解析;
mips-linux-gnu-g++ -EL -shared -fpic testso.cpp -o MyCppModule.so -L./lib -lpython2.7 -I./include/python2.7/
testso.py
# -*- coding: utf-8 -*-  import MyCppModule  #导入python的模块(也就是c的模块,注意so文件名是MyCppModule    r = MyCppModule.MyCppFun1("ls -l")  print r   print MyCppModule.testStringprint MyCppModule.testIntprint "OK" 


PS:PyModule_Create和Py_InitModule的区别:http://stackoverflow.com/questions/10509400/difference-between-pymodinit-func-and-pymodule-create
PyModule_AddStringConstant、PyModule_AddIntConstant的用法



原创粉丝点击