C/C++与Python互相调用

一、【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 python
print '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 python
import sys
print '----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 ctypes
so = 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 ctypes
so = 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.testString
print MyCppModule.testInt
print "OK" 


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



你可能感兴趣的:(C/C++与Python互相调用)