C中嵌入python

时间:2023-03-09 21:58:19
C中嵌入python

嵌入

与python的扩展相对,嵌入是把Python解释器包装到C的程序中。这样做可以给大型的,单一的,要求严格的,私有的并且(或者)极其重要的应用程序内嵌Python解释器的能力。一旦内嵌了Python,世界完全不一样了。

C调用python中的函数:

hw.py:

#coding=utf8

def hw_hs(canshu):
    return canshu

if __name__  == "__main__":
    ccss = "I am hw"
    print hw_hs(ccss)

helloWorld.py:

#coding=utf8
import hw

def hello():
    ccss = "I am helloWorld"
    return hw.hw_hs(ccss)

if __name__  == "__main__":
    print hello()

testcpypy.c:

//#include "testcpypy.h"
#include <Python.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    //初始化Python
    Py_Initialize();
    if (!Py_IsInitialized()) {
        printf("Py_Initialize");
        getchar();
        ;
    }      

    //执行python语句
    PyRun_SimpleString("import sys");
    PyRun_SimpleString("sys.path.append('./')");

    PyObject *pModule = NULL;
    PyObject *pFunc = NULL;
    PyObject *reslt =NULL;

    //载入python模块
    if(!(pModule = PyImport_ImportModule("helloWorld"))) {
        printf("PyImport_ImportModule");
        getchar();
        ;
    }

    //查找函数
    pFunc = PyObject_GetAttrString(pModule, "hello");
    if ( !pFunc || !PyCallable_Check(pFunc) )
    {
        printf("can't find function [hello]");
        getchar();
        ;
    }

    //调用python中的函数
    reslt = (PyObject*)PyEval_CallObject(pFunc, NULL);
    //printf("function return value : %d\r\n", PyInt_AsLong(reslt));  

    //将python返回的对象转换为C的字符串
    char *resltc=NULL;
    int res;
    res = PyArg_Parse(reslt, "s", &resltc);
    if (!res) {
        printf("PyArg_Parse");
        getchar();
        ;
    }
    printf("resltc is %s", resltc);
    getchar();

    //释放内存
    Py_DECREF(reslt);
    Py_DECREF(pFunc);
    Py_DECREF(pModule);  

    //关闭python
    Py_Finalize();

    ;
}

编译:

gcc -o testcpypy testcpypy.c  -IC:\Python27\include -LC:\Python27\libs -lpython27    ---C:\Python27为python安装目录

或:
gcc -c testcpypy.c -IC:\Python27\include
gcc -o testcpypy.exe testcpypy.o -LC:\Python27\libs -lpython27

执行结果:

C中嵌入python


带参数的情况:

#include "callpydll.h"
#include "Python.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>

int callhello(char *instr, char *outstr)
{

    PyObject *pModule = NULL;
    PyObject *pFunc = NULL;
    PyObject *reslt = NULL;
    PyObject *pParm = NULL;

    char *resltc = NULL;
    int resltn;
    int res;

    char *helloWorld = "TestIM_ProtocBuf";

    char *im_account = "aaaa";
    char *auth_code = "aaaa";
    char *im_uid = "aaaa";
    char *proxy_topic = "";

    //初始化Python
    Py_Initialize();
    if (!Py_IsInitialized()) {
        printf("Py_Initialize");
        getchar();
        ;
    }      

    //执行python语句
    PyRun_SimpleString("import sys");
    PyRun_SimpleString("sys.path.append('./')");

    //载入python模块
    if(!(pModule = PyImport_ImportModule(helloWorld))) {
        printf("PyImport_ImportModule");
        getchar();
        ;
    }

    //查找函数
    pFunc = PyObject_GetAttrString(pModule, "login_proxy_body_serialize");
    if ( !pFunc || !PyCallable_Check(pFunc) )
    {
        printf("can't find function [hello]");
        getchar();
        ;
    }

    //参数转换C --> python, 参数必须是元组(一个参数也是,否则会失败!!!坑啊)
    pParm = Py_BuildValue("(ssss)", im_account, auth_code, im_uid, proxy_topic);

    //调用python中的函数
    reslt = (PyObject*)PyEval_CallObject(pFunc, pParm);

    //将python返回的对象转换为C的字符串
    res = PyArg_ParseTuple(reslt, "si", &resltc, &resltn);
    if (!res) {
        printf("PyArg_Parse");
        getchar();
        ;
    }

    printf("resltn is %d", resltn);
    memcpy(outstr, resltc, strlen(resltc)+); 

    //释放内存
    Py_DECREF(reslt);
    Py_DECREF(pFunc);
    Py_DECREF(pModule);
    Py_DECREF(pParm);

    //关闭python
    Py_Finalize();

    ;
}

int main() {
    int i;
    char *dais = "iammain";
    ];
    memset(res,'\0',sizeof(res));

    i = callhello(dais, res);
     != i) {
        printf("Notify:error");
        getchar();
        ;
    }
    printf("result is %s", res);
    getchar();
    ;
}