大致計劃如下(測試平台僅限於Windows 和 Linux,編譯器限於 MSVC、Mingw及linux gcc):
如果只是簡單地調用系統調用或c函數,應該考慮使用ctypes。但傳統方式更通用,比如C模塊中同時要調用python。
//hellomodule.c
#include <Python.h>
#include <string.h>
static PyObject * message(PyObject *self, PyObject *args)
{
char *src, res[100];
if (! PyArg_Parse(args, "(s)", &src))
{
return NULL;
}
else
{
strcpy(res, "Hello, ");
strcat(res, src);
return Py_BuildValue("s", res);
}
}
static struct PyMethodDef methods[] =
{
//導出到Python中的名字、函數指針,參數類型,函數描述
{"message", message, 1, "descript of message"},
//結束
{NULL, NULL, 0, NULL}
};
PyMODINIT_FUNC inithello()
{
// 導出的模塊名,前面結構數組的指針
(void) Py_InitModule("hello", methods);
}
先定義一個函數,函數的參數和返回值都是 PyObject* 類型。(函數內需要將其轉成C語言的類型,最後轉成PyObject* 類型返回)
定義一個 init 函數,該函數在模塊被導入時執行。前面的 PyMODINIT 隱藏windows下 __declspec(dllexport)這個東西
cl /LD hellomodule.c /ID:\python26\include /LIBPATH:D:\python26\libs D:\python26\libs\python26.lib /ohello.pyd
gcc hellomodule.c -shared -ID:\Python26\include -LD:\Python26\libs -lpython26 -o hello.pyd
gcc -shared hellomodule.c -I/usr/include/python2.6 -ohello.so -L/usr/lib/python2.6 -lpython2.6
前面都是直接調用編譯器來生成C模塊,有時輸這麼多命令總是不太方便。幸好,Python 在這方面提供了一個工具。 我們只需要編寫一個簡單的Python文件:
#setup.py
from distutils.core import setup, Extension
example_mod = Extension('hello', sources = ['hellomodule.c'])
setup(name = "hello",
version = "1.0",
description = "A sample extension module",
ext_modules = [example_mod], #setup()中,只有這行是必須的
)
然後執行
python setup.py build
即可。
也可以直接執行
python setup.py install
將模塊安裝到Python路徑下
import hello
print hello.message("OK")
備忘:小插曲,采用msvc編譯後,運行時始終找不到 message 函數。最終發現和注釋中有中文有關(可能是和unix的換行符結合使用的問題),細節部分序進一步試驗。
包含 #include <Python.h>
方法函數(主角) PyObject* func(PyObject* self, PyObject * args)