python 调用 c 函数
最近对lua加密,用到了xxtea_encrypt,打算用python写个工具,直接python调用c.
// xxtea_Encrypt.cpp : 定义控制台应用程序的入口点。
//
#include "xxtea.h"
#include "Python.h"
PyObject* xxtea_encrypt(PyObject* self, PyObject* args)
{
unsigned char *data = NULL;
unsigned char *key = NULL;
unsigned int dataLen = 0;
unsigned int keyLen = 0;
unsigned int retLen = 0;
if (! PyArg_ParseTuple(args, "s#s#", &data,&dataLen,&key,&keyLen))
return NULL;
unsigned char * encrypt = xxtea_encrypt(data,dataLen,key,keyLen,&retLen);
return Py_BuildValue("s#",encrypt,retLen);
}
PyObject* xxtea_decrypt(PyObject* self, PyObject* args)
{
unsigned char *data = NULL;
unsigned char *key = NULL;
unsigned int dataLen = 0;
unsigned int keyLen = 0;
unsigned int retLen = 0;
if (! PyArg_ParseTuple(args, "s#s#", &data,&dataLen,&key,&keyLen))
return NULL;
unsigned char * decrypt = xxtea_decrypt(data,dataLen,key,keyLen,&retLen);
return Py_BuildValue("s#",decrypt,retLen);
}
static PyMethodDef xxteaMethods[] =
{
{"encrypt", xxtea_encrypt, METH_VARARGS, "xxteaEncrypt"},
{"decrypt", xxtea_decrypt, METH_VARARGS, "xxteaDecrypt"},
{NULL, NULL}
};
void initxxteaModule()
{
PyObject* m;
m = Py_InitModule("xxteaModule", xxteaMethods);
}
initxxteaModule python封装头,函数名为init+module名(Py_InitModule的第一个参数)。python导包时,会用到 import xxteaModule.
Py_InitModule第二个参数,c函数的相关描述信息。
struct PyMethodDef {
const char *ml_name; /* The name of the built-in function/method */
PyCFunction ml_meth; /* The C function that implements it */
int ml_flags; /* Combination of METH_xxx flags, which mostly
describe the args expected by the C func */
const char *ml_doc; /* The __doc__ attribute, or NULL */
};
然后就是对c函数的封装,主要是c到python变量的一些转换.
最后说一下编译,这个网上很多都没有说清楚。写一个setup.py.
from distutils.core import setup, Extension
MOD = 'xxteaModule'
setup (name = MOD,ext_modules = [Extension(name=MOD, sources = ['xxtea_Encrypt.cpp','xxtea.cpp'])])
cmd 下执行命令:python setup.py build
将生成的build\lib.win32-2.7\xxteaModule.pyd拷贝到python DLLs目录中。
来看调用的例子。
import xxteaModule
def EncodeWithXxteaModule(filePath,key,signment):
all_the_text = ReadFile(filePath)
if all_the_text[:len(signment)] == signment :
return
#bak lua
BakFile(filePath,all_the_text)
encrypt = xxteaModule.encrypt(all_the_text,key)
signment = signment + encrypt
WriteFile(filePath,signment)
要注意的是,编译pyd时,机器必须安装vs2008,如果要使用其它编译器,改Python27\Lib\distutils\msvc9compiler.py 。关键代码:vc_env = query_vcvarsall(VERSION, plat_spec)