This article describes how to extend Python with the C language. As an example, add a function for Python to set the string to the Windows clipboard (Clipboard). The environment I used to write the following code is: Windows XP, Gcc.exe 4.7.2, Python 3.2.3.
The first step is to compose the C language DLL
Create a clip.c file that reads as follows:
| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 |
// 设置 UNICODE 库,这样的话才可以正确复制宽字符集 #define UNICODE #include <windows.h> #include <python.h> // 设置文本到剪切板(Clipboard) static PyObject *setclip(PyObject *self, PyObject *args) { LPTSTRlptstrCopy; HGLOBAL hglbCopy; Py_UNICODE *content; int len = 0; // 将 python 的 UNICODE 字符串及长度传入 if (!PyArg_ParseTuple(args, "u#", &content, &len)) return NULL; Py_INCREF(Py_None); if (!OpenClipboard(NULL)) return Py_None; EmptyClipboard(); hglbCopy = GlobalAlloc(GMEM_MOVEABLE, (len+1) * sizeof(Py_UNICODE)); if (hglbCopy == NULL) { CloseClipboard(); return Py_None; } lptstrCopy = GlobalLock(hglbCopy); memcpy(lptstrCopy, content, len * sizeof(Py_UNICODE)); lptstrCopy[len] = (Py_UNICODE) 0; GlobalUnlock(hglbCopy); SetClipboardData(CF_UNICODETEXT, hglbCopy); CloseClipboard(); return Py_None; } // 定义导出给 python 的方法 static PyMethodDef ClipMethods[] = { {"setclip", setclip, METH_VARARGS, "Set string to clip."}, {NULL, NULL, 0, NULL} }; // 定义 python 的 model static struct PyModuleDef clipmodule = { PyModuleDef_HEAD_INIT, "clip", NULL, -1, ClipMethods }; // 初始化 python model PyMODINIT_FUNC PyInit_clip(void) { return PyModule_Create(&clipmodule); } |
The second step is to write the Python setup.py
Create a setup.py file that reads as follows:
| 123456789 |
from distutils.core import setup, Extension module1 = Extension(‘clip‘, sources = [‘clip.c‘]) setup (name = ‘clip‘, version = ‘1.0‘, description = ‘This is a clip package‘, ext_modules = [module1]) |
The third step is to compile with Python
Run the following command:
Python setup.py build--compiler=mingw32 Install
The following error is prompted in my environment:
gcc:error:unrecognized command line option '-mno-cygwin '
Error:command ' gcc ' failed with exit status 1
Open the%python installation directory%/lib/distutils/cygwinccompiler.py file, delete the-mno-cygwin inside, and then run it again.
After normal operation, a Clip.pyd file is generated and the file is copied to the%python installation directory%/lib/site-packages directory
The fourth step tests the extension
Write a test.py that reads as follows:
| 123 |
# -*- encoding: gbk -*- importclip clip.setclip("Hello python") |
Run
Python test.py
Paste it anywhere else to verify that it is correct.
***************************************************************************************************
A python extension is a common C language library that, for UNIX computers, usually ends with. So (representing shared objects). A python module divides the code into 3 parts:
(1) C function to be presented as module interface;
(2) Mapping the names of those functions seen by Python developers to a table of C functions in the extension module;
(3) initialization function;
Most extension modules can be contained in a separate C source file, which is called a glue file that launches a file containing Python.h, which allows access to the internal Python
APIs, which associate modules with interpreters. The three sections above are explained below.
****************************************************************************************************
C function Signature:
The signature of the C language implementation of the function is always in one of the following three forms
(1) Pyobject
*myfunction (Pyobject *self, Pyobject *args);
(2) Pyobject
*myfunction (Pyobject *self, Pyobject *args, Pyobject *kw);
(3) Pyobject
*myfunction (Pyobject
*self);
Typically, the C function takes the first form, and the arguments passed to these functions are wrapped in a tuple, and in order to use these parameters, they must be decomposed, using the Pyarg_parsetuple function and the Pyarg_parsetupleandkeywords function
Pyarg_parsetuple (args
, "IDs", &i, &d, &s)
The args are divided into int, double, char*, respectively, I, D,
S
****************************************************************************************************
Method Table:
A method table is a simple array of pymethoddef structures
struct
Pymethoddef
{
Char
*ml_name; #Python中使用的名字
Pycfunction
Ml_meth; #C函数的名字
Int
Ml_flags; #表示使用哪种C函数的签名形式
Char
Ml_doc;
#函数的字符串文档
};
The ml_flags indicates to the interpreter which of the three signatures the Ml_meth is using. The value of ml_flags is usually meth_varargs. If you want to introduce a keyword argument into a function, this value can be either bitwise OR with meth_keywords. Its value can also be meth_noargs, which means that you do not want to accept any form of argument.
The following is an example of a table containing the function MyFunction:
static pymethoddef myfunction[] = {
{"Pythonname",
(pycfuntion) MyFunction, Meth_noargs, "My First function"},
{NULL,
NULL, 0,
NULL}
};
****************************************************************************************************
initialization function:
The last part of the extension module is the initialization function. This function is called by the Python interpreter when the module is loaded. You need to name the function init module name, for example Initchenhuan, module named Chenhuan
****************************************************************************************************
The following is a typical C extension module:
Personal comparison like to use g++ to compile, error and warming distinguish is very clear, the format is as follows:
g++-wall-shared-i/usr/local/python2.6 foo.c-o
foo.so
If you succeed, you will be able to use this module by generating foo.so under the folder:
Python:c Language Extensions