• 如何实现Python调用C代码--python与C之间如何通信(swig)


    转载: https://www.zhihu.com/question/23003213

    1. C代码如何调用Python

    1.1 test

    #include <Python.h>    
                           
    int main(int argc, char *argv[])
    {
        Py_SetProgramName(argv[0]);
        Py_Initialize();   
        
        PyRun_SimpleString("print ('Hello Python!')
    ");
    
        Py_Finalize();
    
        return 0;
    
    }

    Linux下执行:

    gcc -Wall cpython01.c -o cpython01.out -I/usr/include/python2.7 -lpython2.7

    注意是Python2.7不是python3...不然好像报错....

    1.2 C调用Python函数

    great_module.py

    #!/usr/bin/python3     
    #-*- coding:utf-8 -*-  
    
    def great_function(a):
        return a + 1     

    include_module_from_py.c

    #include <stdio.h>
    #include <Python.h>
    
    int include_module_from_py(int a)
    {
        int res = 0;
        PyObject *pModule, *pFunc;
        PyObject *pArgs, *pValue;
    
        //import great_module.py 
        pModule = PyImport_Import(PyString_FromString("great_module"));  //
    
        //great_module.great_function(args)
        pFunc = PyObject_GetAttrString(pModule, "great_function");
    
        //build args
        pArgs = PyTuple_New(1);                           //Pyxxx_new录创建类型为xxx的变量
        PyTuple_SetItem(pArgs, 0, PyInt_FromLong(a));     //若a为tuple, 则a[i]=b对应于 PyTuple_SetItem(a, i, b)
    
        //call
        pValue = PyObject_CallObject(pFunc, pArgs);
    
        res = PyInt_AsLong(pValue);   
    
        return res;
    }
    
    int main()
    {
    
        Py_Initialize();
    
        printf("res = %d
    ", include_module_from_py(3));
    
        Py_Finalize();
    
        return 0;
    }

    运行时,需要先: 

    export PYTHONPATH=.:$PYTHONPATH

    编译:

    gcc -Wall include_module_from_py.c -o include_module.out -I/usr/include/python2.7 -lpython2.7

    2. python调用C/C++

    great_module.c
    #include <stdio.h>
    #include <Python.h>
    
    int great_function(int a)
    {
        return a + 1;
    }
    
    static PyObject * _great_function(PyObject *self, PyObject *args)
    {
        int _a; 
        int res;
    
        //负责将Python的参数转换为C的参数
        if (!PyArg_ParseTuple(args, "i", &_a))
        {   
            return NULL;
        }   
    
        res = great_function(_a);
    
        return PyLong_FromLong(res);
    
    }
    
    //导出表, 负责告诉Python这个模块有哪些函数可以被Python调用
    static PyMethodDef GreateModuleMethods[] = { 
        {   
            "great_function",         // 函数名
            _great_function,          // 包裹函数
            METH_VARARGS,             // 参数变长 
            ""                        // 说明性文字
        },  
        { NULL, NULL, 0, NULL }       //总是如此 
    };
    
    //导出函数, 名字: module名称+前缀init
    PyMODINIT_FUNC initgreat_module()
    {
    
        (void) Py_InitModule("great_module", GreateModuleMethods);
    }
    gcc -fPIC -shared great_module.c -o great_module.so -I/usr/include/python2.7 -lpython2.7

    3. ctypes: Python调用C

    #include <stdio.h>
    
    int add_int(int a, int b)
    {
        return a + b;
    }
    
    double add_double(double a, double b)
    {
        return a + b;
    }
    gcc -shared -Wl,-soname,adder -o adder.so -fPIC add.c
    #!/usr/bin/python3
    #-*- coding:utf-8 -*-
    
    from ctypes import *
    
    
    adder = CDLL('./adder.so')
    
    
    res_int = adder.add_int(4, 5)
    print("4 + 5 = %d " % (res_int))
    
    a = c_double(5.5)
    b = c_double(4.1)
    
    add_double = adder.add_double
    add_double.restype = c_double 
    print("5.5 + 4.1 = ", str(add_double(a, b)))

    工作中用了之后, 想想看还是用ctypes方便点....工程生成.so动态链接库, 然后直接在Python里导入. 

    最好是在C代码中, 将需要的功能接口写的易调用点!! 然后Python也不需要传很多的参数, 直接获取一个结果等等...

    4. 使用SWIG使Python调用C/C++ 

    example.h

    #include <iostream>
    using namespace std;
    
    class Example {
        public:
            void say_hello();
        
    };

    example.cpp

    #include "example.h"
    
    void Example::say_hello()
    {
        cout << "hello
    ";
    }

    example.i

    %module example
    %{
    #include "example.h"
    %}
    %include "example.h"

    setup.py

    #!/usr/bin/python3
    #-*- coding:utf-8 -*-
    
    """
    setup.py file for SWIG C++/Python example
    """
    from distutils.core import setup, Extension
    
    example_module = Extension('_example',
        sources=['example.cpp', 'example_wrap.cxx',],
    )
    
    setup (
        name = 'example',
        version = '0.1',
        author = "douzi",
        description = """Simple swig C++/Python example""",
        ext_modules = [example_module],
        py_modules = ["example"],
    )

    然后使用:

    swig -c++ -python example.i
    python3 setup.py build_ext --inplace

     https://blog.csdn.net/gxt_gy/article/details/50341215

  • 相关阅读:
    WCF上传下载文件
    WCF使用相关
    .net WCF WF4.5 状态机、书签与持久化
    .net WCF WF4.5
    CSS小东西
    asp.net mvc导出execl_转载
    winform自定义控件开发
    html问题汇总
    工作中的小东西
    jQuery事件
  • 原文地址:https://www.cnblogs.com/douzujun/p/10738959.html
Copyright © 2020-2023  润新知