关键词:c,python拓展,import
1. 测试环境
- python2.7
- gcc7.5
2. 拓展
修改自:https://www.cnblogs.com/zhangdewang/p/8685594.html
foo.c
#include <Python.h>
//three ways :
/*
PyObject *MyFunction(PyObject *self, PyObject *args);
PyObject *MyFunctionWithKeywords(PyObject *self,
PyObject *args,
PyObject *kw);
PyObject *MyFunctionWithNoArgs(PyObject *self);
*/
//the return Py_RETURN_NONE
static PyObject* foo_bar(PyObject *self, PyObject *args)
{
//Do something interesting here0.
Py_RETURN_NONE;
}
static PyObject * foo_baz(PyObject *self, PyObject *args)
{
int i;
double d;
char *s;
if(!PyArg_ParseTuple(args, "ids", &i, &d, &s))
{
return NULL;
}
//Do something interesting here.
Py_RETURN_NONE;
}
static PyObject *foo_baz2(PyObject *self, PyObject *args)
{
int i;
double d;
char *s;
int i2 = 4;
double d2 = 5.0;
char *s2 = "six";
if(!PyArg_ParseTuple(args, "ids|ids", &i, &d, &s, &i2, &d2, &s2))
{
return NULL;
}
//Do something interesting here.
Py_RETURN_NONE;
}
static PyObject *foo_quux(PyObject *self, PyObject *args, PyObject* kw)
{
char *kwlist[] = {"i", "d", "s", NULL};
int i;
double d = 2.0;
char *s = "three";
if(!PyArg_ParseTupleAndKeywords(args, kw, "i|ds", kwlist, &i, &d, &s))
{
return NULL;
}
//Do something interesting here.
Py_RETURN_NONE;
}
static PyObject * foo_add(PyObject *self, PyObject *args)
{
int a;
int b;
if(!PyArg_ParseTuple(args, "ii", &a, &b))
{
return NULL;
}
return Py_BuildValue("i", a+b);
/*
*python function is:
def add(a,b):
return a + b
*/
}
static PyObject *foo_add_and_subtract(PyObject *self, PyObject *args)
{
int a;
int b;
if(!PyArg_ParseTuple(args, "ii", &a, &b))
{
return NULL;
}
return Py_BuildValue("(ii)", a+b, a-b);
/*
*python function is:
def add_and_subtrace(a, b):
return (a+b, a-b)
*/
}
/*
struct PyMethodDef {
char *ml_name;//function name in python
PyCfunction ml_meth;//the address the function
int ml_flags;// METH_VARARGS METH_KEYWORDS METH_NOARGS
char *ml_doc;
};
*/
static PyMethodDef foo_methods[] = {
{"bar", (PyCFunction)foo_bar, METH_NOARGS, "My first function."},
{"baz", (PyCFunction)foo_baz, METH_VARARGS, NULL},
{"baz2", (PyCFunction)foo_baz2, METH_VARARGS, NULL},
{"quux", (PyCFunction)foo_quux, METH_VARARGS|METH_KEYWORDS, NULL},
{"add", (PyCFunction)foo_add, METH_VARARGS, NULL},
{"add_and_subtract", (PyCFunction)foo_add_and_subtract, METH_VARARGS, NULL},
{NULL, NULL, 0, NULL}
};
//init function for the python module
PyMODINIT_FUNC initfoo(){//init+moduleName Python解释器规定所有的初始化函数的函数名都必须以init开头,并加上模块的名字
Py_InitModule("foo", foo_methods);
// Py_InitModule("foo", foo_methods, "My first extension module.");
//Py_InitModule("foo", foo_methods, "My first extension module");
}
//how to build te module
/* //in unix or linux:
gcc -shared -fPIC -I/usr/include/python2.7 foo.c -o foo.so
*/
编译
gcc -shared -fPIC -I/usr/include/python2.7 foo.c -o foo.so
就是将foo.c编译成一个动态库
3. 测试
python2.7
Python 2.7.17 (default, Sep 30 2020, 13:38:04)
[GCC 7.5.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import foo
>>> foo.add(3,4)
7
>>> foo.add_and_subtract(3,4)
(7, -1)
>>>
- 猜测python中
import foo
的时候就执行initfoo
函数,然后会返回static的PyMethoDef 的实例,后续在 python 中就可以使用 foo.add 等方法