例一:ctypespython
pycall.clinux
/***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
c++
import ctypes ll = ctypes.cdll.LoadLibrary lib = ll("./libpycall.so") res= lib.foo(1, 3) print ('Result=' ,res)
運行app
$ gcc -o libpycall.so -shared -fPIC pycall.cpython2.7
$ python3 pycall.py 函數
you input 1 and 3測試
Result= 4ui
例子二spa
sumtest.crest
/* * 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()
3、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 -I/usr/include/python2.7 -lpython2.7
$ ./my_python
Today is Sat Apr 9 22:00:22 2016
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 -L/usr/lib -lpython2.7 -Wl,-R/usr/local/lib */ #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 + 1
my_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
4、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