例一:ctypes
pycall.c
/***gcc -o libpycall.so -shared -fPIC pycall.c*/  
#include <stdio.h>  
#include <stdlib.h>  
int foo(int a, int b)  
{  
  printf("you input %d and %d\n", a, b);  
  return a+b;  
}pycall.py
import ctypes  
ll = ctypes.cdll.LoadLibrary   
lib = ll("./libpycall.so")    
res=  lib.foo(1, 3)
print ('Result=' ,res)运行
$ gcc -o libpycall.so -shared -fPIC pycall.c
$ python3 pycall.py
you input 1 and 3
Result= 4
例子二
sumtest.c
/*
 * gcc -c -fPIC sumtest.c
 *
 * gcc -shared -fPIC -o sumtest.so sumtest.o
 *
 */
double mysum(double a[], long n){
   double sum = 0;
   int i;
   for(i=0;i<n;i++)
	 sum += a[i];
   return sum;
}编译后产生动态库sumtest.so
测试
>>> import numpy as np
>>> from ctypes import *
>>> sum_test = np.ctypeslib.load_library("./sumtest.so", ".")
>>> print sum_test.mysum
<_FuncPtr object at 0x7faae6fa6ef0>
>>> sum_test.mysum.argtypes = [POINTER(c_double), c_long]
>>> sum_test.mysum.restype = c_double
>>> x = np.arange(1, 101, 1.0)
>>> sum_test.mysum(x.ctypes.data_as(POINTER(c_double)), len(x))
5050.0
>>> def mysum(x):
...     return sum_test.mysum(x.ctypes.data_as(POINTER(c_double)), len(x))
... 
>>> x = np.arange(1,11,1.0)
>>> mysum(x[::2])
15.0
>>> quit()三、c中调用python
(1)例一
/*  filename:my_python.c
 *  gcc my_python.c -o my_python -I/usr/include/python2.7 -lpython2.7
 */
#include <Python.h>
int main(int argc, char *argv[])
{
  Py_SetProgramName(argv[0]);
  Py_Initialize();
  PyRun_SimpleString("from time import time,ctime");
  PyRun_SimpleString("print 'Today is',ctime(time())\n");
  PyRun_SimpleString("print ('Hello Python in c!'\n)");
  Py_Finalize();
  return 0;
}运行:
$ gcc my_python.c -o my_python `pkg-config --cflags --libs python`
$ ./my_python
Today is Sat Apr 9 22:00:22 2016
Hello Python in c!
mingw环境:
D:\prg\py\mypyc>gcc my_python.c -o my_python  -IC:\Users\wangxw\AppData\Local\Programs\Python\Python37\include -LC:\Users\wangxw\AppData\Local\Programs\Python\Python37\libs -lpython37
D:\prg\py\mypyc>my_python.exe
Today is Sun Nov 24 19:16:34 2019
Hello Python in c!(2)例二
euclid_module.py
def euclid(a, b):
    while b:
        a, b = b, a%b
    return a
euclidpy.c
/**
 * @file euclidpy.c
 * gcc -Wall -O2 -o euclidpy euclidpy.c -I/usr/include/python2.7 -lpython2.7
 * gcc -Wall -O2 -o euclidpy euclidpy.c `pkg-config --cflags --libs python` 
 */ 
#include <Python.h>
#include <stdio.h>
int main()
{
    //初始化python
    Py_Initialize();
    if (!Py_IsInitialized()) {
        printf("Python_Initialize failed\n");
        return 1;
    }   
    PyObject *pModule = NULL;
    PyObject *pFunc   = NULL;
    PyObject *pArg    = NULL;
    PyObject *result  = NULL;
    PyRun_SimpleString("import sys");                                   //直接执行python语句
    PyRun_SimpleString("import sys;sys.path.append('.')");
    pModule = PyImport_ImportModule("euclid_module");
    if (pModule == NULL) {
        printf("import module failed!\n");
        return -1;
    }  
    pFunc   = PyObject_GetAttrString(pModule, "euclid");
    pArg    = Py_BuildValue("(i, i)", 120, 48);
    //调用函数,并得到python类型的返回值
    result =PyEval_CallObject(pFunc,pArg);
    //c用来保存c/c++类型的返回值
    int c;
    //将python类型的返回值转换为c/c++类型
    PyArg_Parse(result, "i", &c);
    //输出返回值
    printf("The Greatest Common Divisor (GCD) is:%d\n", c);
    
    Py_Finalize();
    return 0;
}运行:
$ gcc -Wall -O2 -o euclidpy euclidpy.c -I/usr/include/python2.7 -L/usr/lib -lpython2.7 -Wl,-R/usr/local/lib
$ ./euclidpy
The Greatest Common Divisor (GCD) is:24
注意:
如果不加sys.path.append('.')的话,需要设置环境变量export PYTHONPATH=.:$PYTHONPATH,不如程序运行时找不到euclid_module模块
(3)例三
foo_module.py
def foo_function(a):
    return a + 1my_python1.c
/*
 *  gcc my_python1.c -o my_python1 -I/usr/include/python2.7 -lpython2.7
 *
 * */
#include <Python.h>
int foo_function_from_python(int a) {
    int res;
    PyObject *pModule,*pFunc;
    PyObject *pArgs, *pValue;
    
    /* import */
    pModule = PyImport_Import(PyString_FromString("foo_module"));
    /* great_module.great_function */
    pFunc = PyObject_GetAttrString(pModule, "foo_function"); 
    
    /* build args */
    pArgs = PyTuple_New(1);
    PyTuple_SetItem(pArgs,0, PyInt_FromLong(a));
      
    /* call */
    pValue = PyObject_CallObject(pFunc, pArgs);
    
    res = PyInt_AsLong(pValue);
    return res;
}
int main(int argc, char *argv[]) {
    Py_Initialize();
    PyRun_SimpleString("import sys");                                   //直接执行python语句
    PyRun_SimpleString("import sys;sys.path.append('.')");
    printf("The result=%d!\n",foo_function_from_python(2));
    Py_Finalize();
}$ ./my_python1
The result=3!
(4)例四:cython
helloworld.pyx
cdef public SayHello():
    return str("hello,world\n")helloworld_cython.c
/* filename:helloworld_cython.c
 * gcc helloworld_cython.c helloworld.c -o helloworld_cython -I/usr/include/python2.7 -lpython2.7
 */
#include <Python.h>
#include "helloworld.h"
int main(int argc, char *argv[]) {
    Py_Initialize();
    inithelloworld();
    printf("%s\n",PyString_AsString(
                SayHello()
            ));
    Py_Finalize();
}其中inithelloworld在helloworld.pyx编译后生成的helloworld.h中定义,用于python2,python3用PyInit_helloworld
运行:
$ cython helloworld.pyx
$ gcc helloworld_cython.c helloworld.c -o helloworld_cython -I/usr/include/python2.7 -lpython2.7
$ ./helloworld_cython
hello,world
再举一例:
great_module.pyx
#cython great_module.pyx
cdef public great_function(a,index):
    return a[index]my_cython.c
/* filename:my_cython.c
 * gcc my_cython.c great_module.c -o my_cython -I/usr/include/python2.7 -lpython2.7
 */
#include <Python.h>
#include "great_module.h"
int main(int argc, char *argv[]) {
    PyObject *tuple;
    Py_Initialize();
    initgreat_module();
    printf("%s\n",PyString_AsString(
                great_function(
                    PyString_FromString("hello"),
                    PyInt_FromLong(4)
                )
            ));
    tuple = Py_BuildValue("(iis)", 1, 2, "three");
    printf("%ld\n",PyInt_AsLong(
                great_function(
                    tuple,
                    PyInt_FromLong(1)
                )
            ));
    printf("%s\n",PyString_AsString(
                great_function(
                    tuple,
                    PyInt_FromLong(2)
                )
            ));
    Py_Finalize();
}运行结果:
$ ./my_cython
o
2
three
四、c编写python模块
mytest.c
// gcc -shared -fPIC -I /usr/include/python2.7 mytest.c -o mytest.so
#include <Python.h>
static PyObject* add(PyObject* self, PyObject* args){
	int a=0;
	int b=0;
	if(!PyArg_ParseTuple(args,"i|i",&a,&b))
	  return NULL;
	return Py_BuildValue("i", a+b);
}
static PyObject* sub(PyObject* self, PyObject* args){
	int a=0;
	int b=0;
	if(!PyArg_ParseTuple(args,"i|i",&a,&b))
	  return NULL;
	return Py_BuildValue("i", a-b);
}
static PyMethodDef addMethods[]={
	{"add", add, METH_VARARGS},
	{"sub", sub, METH_VARARGS},
	{NULL,NULL,0,NULL}
};
void initmytest(){
	Py_InitModule("mytest", addMethods);
}运行:
gcc -shared -fPIC -I /usr/include/python2.7 mytest.c -o mytest.so
生成python可装载的mytest模块
$ python
Python 2.7.6 (default, Jun 22 2015, 17:58:13)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import mytest
>>> mytest.add(10,20)
30
>>> mytest.sub(10,5)
5
来源:oschina
链接:https://my.oschina.net/u/2245781/blog/654848