我正在尝试移植这个 Python extension与 Python 3 一起工作。Python 3 对 Python C/C++ API 进行了许多更改,需要修改遗留模块的初始化和参数传递函数。到目前为止,我采用了旧的 Python 2 代码:
#include <Python.h>
#include <openssl/crypto.h>
static PyObject* SecureString_clearmem(PyObject *self, PyObject *str) {
char *buffer;
Py_ssize_t length;
if (PyString_AsStringAndSize(str, &buffer, &length) != -1) {
OPENSSL_cleanse(buffer, length);
}
return Py_BuildValue("");
}
static PyMethodDef SecureStringMethods[] = {
{"clearmem", SecureString_clearmem, METH_O,
PyDoc_STR("clear the memory of the string")},
{NULL, NULL, 0, NULL},
};
PyMODINIT_FUNC initSecureString(void)
{
(void) Py_InitModule("SecureString", SecureStringMethods);
}
我按照this example做了这个:
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <openssl/crypto.h>
static PyObject* SecureString_clearmem(PyObject *self, PyObject *args) {
char *buffer;
Py_ssize_t length;
if(!PyArg_ParseTuple(args, "s#", &buffer, &length)) {
return NULL;
}
OPENSSL_cleanse(buffer, length);
Py_RETURN_NONE;
}
static PyMethodDef SecureStringMethods[] = {
{"SecureString_clearmem", SecureString_clearmem, METH_VARARGS, "clear the memory of the string"},
{NULL, NULL, 0, NULL},
};
static struct PyMethodDef SecureStringDef = {
PyModuleDef_HEAD_INIT,
"SecureString",
NULL,
-1,
SecureStringMethods,
};
PyMODINIT_FUNC PyInit_SecureString(void) {
Py_Initialize();
return PyModule_Create(&SecureStringDef);
}
理论上,这应该遵循模块初始化、参数传递和字符串大小变量的新 Python 3 规则。它成功编译和安装(我使用的是与项目一起分发的相同 setup.py),但是当我尝试导入它时:
import SecureString
我得到一个段错误:
Segmentation fault: 11
我试图附加 gdb 来检查 C 代码,但是 gdb 不能在我的计算机上使用 Python C 模块。我也曾尝试注释掉 OpenSSL 代码以查看这是否是问题的根源,但无济于事。我的 Python3 安装运行其他不使用此库的程序。有人可以看看这个并建议我应该看哪里或下一步应该尝试什么吗?
谢谢!
最佳答案
段错误很可能是由于您将模块结构定义为 PyMethodDef
而不是 PyModuleDef
引起的:
static struct PyModuleDef SecureStringDef
除此之外。我不确定您为什么在初始化函数中调用了 Py_Initialize
。调用它是一个空操作(因为当你调用它时你已经在一个初始化的解释器中运行)。
顺便说一句,不需要要点,Python 已经有了 information关于如何从 2 移植到 3。
关于Python 3 C扩展导入时出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44641919/