我使用c来编写python扩展名 我使用c程序加密字符串 我的c程序:
#include <Python.h>
static const char *codes = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static const unsigned char map[256] = {
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 253, 255,
255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 253, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,
255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255
};
int length(char *str){
int i = 0;
while (str[i] != '\0') i++;
return i;
}
char *str_encrypt(char *in) {
unsigned long len = (unsigned long)length(in);
unsigned long index, l_even;
char *p;
char *out = (char *) PyMem_Malloc (len * 4 / 3 + 1);
p = out;
/* valid output size ? */
l_even = 3 * (len / 3);
for (index = 0; index < l_even; index += 3) {
*p++ = codes[in[0] >> 2];
*p++ = codes[((in[0] & 3) << 4) + (in[1] >> 4)];
*p++ = codes[((in[1] & 0xf) << 2) + (in[2] >> 6)];
*p++ = codes[in[2] & 0x3f];
in += 3;
}
/* Pad it if necessary... */
if (index < len) {
unsigned a = (unsigned)in[0];
unsigned b = (unsigned)((index+1 < len) ? in[1] : 0);
unsigned c = 0;
*p++ = codes[a >> 2];
*p++ = codes[((a & 3) << 4) + (b >> 4)];
*p++ = (char)((index+1 < len) ? codes[((b & 0xf) << 2) + (c >> 6)] : '=');
*p++ = '=';
}
/* append a NULL byte */
*p = '\0';
return out;
}
static PyObject *wrap_encrypt_str(PyObject *self, PyObject *args) {
char *input_str;
if (!PyArg_ParseTuple(args, "s", &input_str)) {
return NULL;
}
char *result = str_encrypt(input_str);
PyObject *pyObject = Py_BuildValue("s", result);
PyMem_Free(result);
return pyObject;
}
/* registration table */
static PyMethodDef wrap_methods[] ={
{"encrypt_str", wrap_encrypt_str, METH_VARARGS}, /* method name, C func ptr, always-tuple */
{NULL, NULL} /* end of table marker */
};
/* module initializer */
PyMODINIT_FUNC initencryption(void) /* called on first import */
{ /* name matters if loaded dynamically */
(void) Py_InitModule("encryption", wrap_methods); /* mod name, table ptr */
}
然后我写了一个名为setup.py的文件。
setup.py中的程序在这里:
from setuptools import setup, Extension
setup(
name="extest",
packages=["extest", "extest.math", "extest.test"],
version="0.0.1",
zip_safe=False,
ext_modules=[
Extension("extest.test.encryption", sources=['extest/test/encryption.c'], extra_compile_args=["-Wno-char-subscripts"])
],
long_description='',
classifiers=[
"Environment :: Web Environment",
"Intended Audience :: Developers",
"Operating System :: OS Independent",
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7'
]
)
我运行python setup.py install
并成功安装扩展程序
我在python程序中导入模块
像这样:
from extest.test.encryption import encrypt_str
a = encrypt_str("asdfg")
print a
成功运行。
但是当我用a = encrypt_str("asdfg")
替换a = encrypt_str("/static/hello.js")
时,我收到错误,程序崩溃了!
错误信息在这里:
*** Error in `python': corrupted size vs. prev_size: 0x0000000000aaca00 ***
是什么原因?如何解决?
答案 0 :(得分:3)
你没有为值out
设置malloc足够的内存,
我将此行代码char *out = (char *) PyMem_Malloc (len * 4 / 3 + 1);
修改为char *out = (char *) PyMem_Malloc (len * 2);
,然后重新生成此程序。我看到问题已经解决了。
答案 1 :(得分:0)
您在3个字节的块中迭代in
,并为每个块写入4个字节到out
。然后,最后,你用4个字节填充(如果in
不是3的倍数),最后,你附加一个空字节。
所以你需要分配4 * ((len + 2) / 3) + 1
个字节。
为了验证这是否正确,我们可以看一些小例子: 如果len为0,则只需要1个字节用于null。 如果len是1或2,则需要4个字节的填充,加上null。 如果len为3,则单个块需要4个字节,加上null。 如果len为4,则单个块需要4个字节,加上4个字节的填充,加上null。 等等。