python c++ extension
在调试PIL的扩展Agg中对python的c扩展感到了好奇,所幸研究了一下python的c扩展。并自己根据例子写了一下效果还不错,以下代码供大家学习:)
我本人对c不大了解,欢迎大家,分析install 流程 :)
执行结果:
http://dl.iteye.com/upload/picture/pic/81573/f70076d3-8ea1-341b-af6f-cef3c8118389.png
编写代码spam.cxx
/*How to use :import spamstatus = spam.system("ls -l")dome is C++ Extension*/#define VERSION "1.2a3"#if defined(_MSC_VER)#define WINDOWS_LEAN_AND_MEAN#include <windows.h>#endif#include "Python.h"#if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x01060000#if PY_VERSION_HEX< 0x02020000 || defined(Py_USING_UNICODE)/* defining this enables unicode support (default under 1.6a1 and later) */#define HAVE_UNICODE#endif#endif/* Function Define and AttributesDefine */static PyObject *CmdError;static PyObject *cmd(PyObject *self, PyObject *args){ const char *command; int sts;/*int PyArg_ParseTuple(PyObject *args, const char *format, ...) return true or false | exception*/ if (!PyArg_ParseTuple(args, "s", &command)){PyErr_SetString(CmdError, "System command failed");return NULL;}else{printf("run command is:"); puts(command); //or use PyObject_Print for debug} sts = system(command);//PyObject* Py_BuildValue(const char *format, ...) return Py_BuildValue("i", sts);}static PyMethodDef CmdMethods[] = { {"cmd", (PyCFunction) cmd, METH_VARARGS}, {NULL, NULL}};/* Initial Modules*/PyMODINIT_FUNCinitspam(void){ PyObject *m; m = Py_InitModule("spam", CmdMethods); if (m == NULL) return;/*PyObject* PyErr_NewException(char *name, PyObject *base, PyObject *dict)*/ CmdError = PyErr_NewException("system.error", NULL, NULL); Py_INCREF(CmdError); PyModule_AddObject(m, "error", CmdError);};extern "C"DL_EXPORT(void)initaggdraw(void){ /* Initialize the Python interpreter.Required. */ Py_Initialize(); /* Add a static module */ initspam();PyObject* g = PyDict_New();PyDict_SetItemString(g, "__builtins__", PyEval_GetBuiltins()); PyRun_String("print 'welcome!'\n", Py_file_input, g, NULL);}
setup.py
from distutils.core import setup, ExtensionmoduleSpam = Extension('spam',sources = ['spammodule.cxx'])setup(name = 'Spam system', version = '1.0', description = 'This is a demo package for run system command', ext_modules = )
跟踪了一下安装过程,发现setup 查找Setup.local文件:
/* 在 Setup.local 文件中我们可以指定输出*/spam spammodule.so
:execve("/usr/bin/python", ["python", "setup.py", "install"], [/* 57 vars */]) = 0104:stat("/usr/bin/Modules/Setup", 0x7fff47082070) = -1 ENOENT (No such file or directory)419:stat("/usr/local/lib64/python2.6/site-packages/setuptools-0.6c11-py2.6.egg", {st_mode=S_IFREG|0644, st_size=333581, ...}) = 0446:open("/usr/local/lib64/python2.6/site-packages/setuptools.pth", O_RDONLY) = 5450:read(5, "./setuptools-0.6c11-py2.6.egg\n", 8192) = 30469:stat("/usr/local/lib64/python2.6/site-packages/setuptools-0.6c11-py2.6.egg", {st_mode=S_IFREG|0644, st_size=333581, ...}) = 0470:open("/usr/local/lib64/python2.6/site-packages/setuptools-0.6c11-py2.6.egg", O_RDONLY) = 42738:lstat("/home/bmc/test/ct/Modules/setup.py", {st_mode=S_IFREG|0644, st_size=262, ...}) = 02739:stat("setup.py", {st_mode=S_IFREG|0644, st_size=262, ...}) = 02740:open("setup.py", O_RDONLY) = 32745:read(3, "from distutils.core import setup"..., 240) = 2402749:stat("setup.py", {st_mode=S_IFREG|0644, st_size=262, ...}) = 02750:open("setup.py", O_RDONLY) = 32756:read(3, "from distutils.core import setup"..., 4096) = 2622853:read(4, "\0\0\0error in %s setup command: %s"..., 4096) = 36173915:stat("setup.cfg", 0x7fff47083e70) = -1 ENOENT (No such file or directory)3999:stat("/usr/bin/Modules/Setup.dist", 0x7fff4707c980) = -1 ENOENT (No such file or directory)4000:stat("/usr/bin/Modules/Setup.local", 0x7fff4707c980) = -1 ENOENT (No such file or directory)
页:
[1]