gpt4 book ai didi

python - 将bytearray从Python传输到C并返回

转载 作者:太空狗 更新时间:2023-10-30 00:26:40 25 4
gpt4 key购买 nike

我需要快速处理 XOR bytearray,在 Python 的一个变体中

for i in range(len(str1)): str1[i]=str1[i] ^ 55

工作很慢
我用 C 编写了这个模块。我对C语言很了解,之前我什么也没写。
在变体中

PyArg_ParseTuple (args, "s", &str))

一切都按预期工作,但我需要使用而不是 s s* 因为元素可以包含嵌入的 null,但是如果我在调用 python 崩溃时将 s 更改为 s*

PyArg_ParseTuple (args, "s*", &str)) // crash

也许像我这样的初学者想用我的例子作为开始写他自己的东西,所以把这个例子中要用到的所有信息都带到Windows上。
在页面上解析参数和构建值 http://docs.python.org/dev/c-api/arg.html

test_xor.c

#include <Python.h>

static PyObject* fast_xor(PyObject* self, PyObject* args)
{
const char* str ;
int i;

if (!PyArg_ParseTuple(args, "s", &str))
return NULL;

for(i=0;i<sizeof(str);i++) {str[i]^=55;};
return Py_BuildValue("s", str);

}

static PyMethodDef fastxorMethods[] =
{
{"fast_xor", fast_xor, METH_VARARGS, "fast_xor desc"},
{NULL, NULL, 0, NULL}
};

PyMODINIT_FUNC

initfastxor(void)
{
(void) Py_InitModule("fastxor", fastxorMethods);
}

test_xor.py

import fastxor
a=fastxor.fast_xor("World") # it works with s instead s*
print a
a=fastxor.fast_xor("Wo\0rld") # It does not work with s instead s*

编译.bat

rem use http://bellard.org/tcc/
tiny_impdef.exe C:\Python26\python26.dll
tcc -shared test_xor.c python26.def -IC:\Python26\include -LC:\Python26\libs -ofastxor.pyd
test_xor.py

最佳答案

您无需构建扩展模块即可快速执行此操作,您可以使用 NumPy。但是对于你的问题,你需要一些像这样的 C 代码:

#include <Python.h>
#include <stdlib.h>

static PyObject * fast_xor(PyObject* self, PyObject* args)
{
const char* str;
char * buf;
Py_ssize_t count;
PyObject * result;
int i;

if (!PyArg_ParseTuple(args, "s#", &str, &count))
{
return NULL;
}

buf = (char *)malloc(count);

for(i=0;i<count;i++)
{
buf[i]=str[i] ^ 55;
}

result = Py_BuildValue("s#", buf, count);
free(buf);
return result;
}

你不能改变字符串对象的内容,因为Python中的字符串是不可变的。您可以使用“s#”获取char * 指针和缓冲区长度。

如果你会使用 NumPy:

In [1]: import fastxor

In [2]: a = "abcdsafasf12q423\0sdfasdf"

In [3]: fastxor.fast_xor(a)
Out[3]: 'VUTSDVQVDQ\x06\x05F\x03\x05\x047DSQVDSQ'


In [5]: import numpy as np

In [6]: (np.frombuffer(a, np.int8)^55).tostring()
Out[6]: 'VUTSDVQVDQ\x06\x05F\x03\x05\x047DSQVDSQ'

In [7]: a = a*10000

In [8]: %timeit fastxor.fast_xor(a)
1000 loops, best of 3: 877 us per loop

In [15]: %timeit (np.frombuffer(a, np.int8)^55).tostring()
1000 loops, best of 3: 1.15 ms per loop

关于python - 将bytearray从Python传输到C并返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15459684/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com