在扩展中使用 PyModule_AddIntConstant()
Using PyModule_AddIntConstant() in an extension
我已经看到 Adding symbolic constants with hex values to Python extension module 并且我正在尝试重现此效果:
#include <Python.h>
#include <Windows.h>
static PyObject * sys_shutdown(PyObject *self, PyObject *args) {
int val;
if (!PyArg_ParseTuple(args, "i", &val))
val = SHTDN_REASON_MINOR_OTHER; // Provide failsafe
ExitWindowsEx(EWX_POWEROFF, val); // Shutdown
return Py_BuildValue("");
}
static PyObject * sys_restart(PyObject *self, PyObject *args) {
int val;
if (!PyArg_ParseTuple(args, "i", &val))
val = SHTDN_REASON_MINOR_OTHER; // Provide failsafe
ExitWindowsEx(EWX_REBOOT, val); // Restart
return Py_BuildValue("");
}
static PyObject * sys_log_out(PyObject *self, PyObject *args) {
int val;
if (!PyArg_ParseTuple(args, "i", &val))
val = SHTDN_REASON_MINOR_OTHER; // Provide failsafe
ExitWindowsEx(EWX_LOGOFF, val); // Log out
return Py_BuildValue("");
}
static PyMethodDef localMethods[] = {
{"shutdown", (PyCFunction)sys_shutdown, METH_VARARGS, "..."},
{"restart", (PyCFunction)sys_restart, METH_VARARGS, "..."},
{"log_out", (PyCFunction)sys_log_out, METH_VARARGS, "..."},
{NULL, NULL, 0, NULL}
};
static struct PyModuleDef func = {
PyModuleDef_HEAD_INIT,
"utilities",
"...",
-1,
localMethods,
};
PyMODINIT_FUNC PyInit_utilities(void) {
PyObject *value;
value = PyModule_New(&func);
PyModule_AddIntConstant(value, "DEFINED", AF_INET);
return PyModule_Create(&func);
}
设置脚本:
from distutils.core import setup, Extension
module = Extension(
"utilities",
sources = ["main.c"],
libraries = ["user32"]
)
setup (
name = "Utilities",
version = "1.0",
ext_modules = [module])
一切都按预期构建,但是我无法在我的扩展中使用 DEFINED
:
import utilities
for i in utilities.__dict__: print(i)
utilities.DEFINED # AttributeError: module 'utilities' has no attribute 'DEFINED'
Returns:
__name__
__doc__
__package__
__loader__
__spec__
shutdown
restart
log_out
__file__
我想像这样返回 value
:
return PyModule_Create(&value);
但是 returns:
LINK : fatal error LNK1104: cannot open file 'build\lib.win32-3.6\WinUtils.cp36-win32.pyd'
error: command 'C:\Program Files (x86)\Microsoft Visual Studio17\WDExpress\VC\Tools\MSVC.14.26428\bin\HostX86\x86\link.exe' failed with exit status 1104
如何将 DEFINED
值添加到我的扩展中(以便我可以 运行 utilities.DEFINED
)?
编辑:
如以下答案中所述,关闭所有内容并再次尝试成功构建扩展,但是使用 return PyModule_Create(&value);
仍然会崩溃。
PyModule_AddIntConstant(value, "DEFINED", DEFINED_VALUE);
是正确的(假设 DEFINED_VALUE
是一个 (C) long
).
结合最后的链接器错误(以及您正在编写代码然后进行测试,等等......)告诉我链接器无法编写新的 .pyd 文件(包含最新更改 - 包括 DEFINED
变量),因为它正被先前启动的 python.exe 使用导入您的模块的进程。
- 关闭 每个 运行ning 解释器导入你的模块(到 "unlock" WinUtils.cp36-win32.pyd)
- 构建(这一次,链接器将能够覆盖文件)
- 测试(运行 你的 Python 代码)
注意:您可以检查函数 return 值 ([Python]: int PyModule_AddIntConstant(PyObject *module, const char *name, long value))。
@EDIT0(关于 2nd 问题):
正如我在我的一条评论中所指出的那样,使用 PyModule_Create
(根据 [Python]: PyObject* PyModule_New(const char *name),您将得到 未定义的行为):
PyMODINIT_FUNC PyInit_utilities() {
PyObject *mod = PyModule_Create(&func);
PyModule_AddIntConstant(mod, "DEFINED", AF_INET);
return mod;
}
我已经看到 Adding symbolic constants with hex values to Python extension module 并且我正在尝试重现此效果:
#include <Python.h>
#include <Windows.h>
static PyObject * sys_shutdown(PyObject *self, PyObject *args) {
int val;
if (!PyArg_ParseTuple(args, "i", &val))
val = SHTDN_REASON_MINOR_OTHER; // Provide failsafe
ExitWindowsEx(EWX_POWEROFF, val); // Shutdown
return Py_BuildValue("");
}
static PyObject * sys_restart(PyObject *self, PyObject *args) {
int val;
if (!PyArg_ParseTuple(args, "i", &val))
val = SHTDN_REASON_MINOR_OTHER; // Provide failsafe
ExitWindowsEx(EWX_REBOOT, val); // Restart
return Py_BuildValue("");
}
static PyObject * sys_log_out(PyObject *self, PyObject *args) {
int val;
if (!PyArg_ParseTuple(args, "i", &val))
val = SHTDN_REASON_MINOR_OTHER; // Provide failsafe
ExitWindowsEx(EWX_LOGOFF, val); // Log out
return Py_BuildValue("");
}
static PyMethodDef localMethods[] = {
{"shutdown", (PyCFunction)sys_shutdown, METH_VARARGS, "..."},
{"restart", (PyCFunction)sys_restart, METH_VARARGS, "..."},
{"log_out", (PyCFunction)sys_log_out, METH_VARARGS, "..."},
{NULL, NULL, 0, NULL}
};
static struct PyModuleDef func = {
PyModuleDef_HEAD_INIT,
"utilities",
"...",
-1,
localMethods,
};
PyMODINIT_FUNC PyInit_utilities(void) {
PyObject *value;
value = PyModule_New(&func);
PyModule_AddIntConstant(value, "DEFINED", AF_INET);
return PyModule_Create(&func);
}
设置脚本:
from distutils.core import setup, Extension
module = Extension(
"utilities",
sources = ["main.c"],
libraries = ["user32"]
)
setup (
name = "Utilities",
version = "1.0",
ext_modules = [module])
一切都按预期构建,但是我无法在我的扩展中使用 DEFINED
:
import utilities
for i in utilities.__dict__: print(i)
utilities.DEFINED # AttributeError: module 'utilities' has no attribute 'DEFINED'
Returns:
__name__
__doc__
__package__
__loader__
__spec__
shutdown
restart
log_out
__file__
我想像这样返回 value
:
return PyModule_Create(&value);
但是 returns:
LINK : fatal error LNK1104: cannot open file 'build\lib.win32-3.6\WinUtils.cp36-win32.pyd' error: command 'C:\Program Files (x86)\Microsoft Visual Studio17\WDExpress\VC\Tools\MSVC.14.26428\bin\HostX86\x86\link.exe' failed with exit status 1104
如何将 DEFINED
值添加到我的扩展中(以便我可以 运行 utilities.DEFINED
)?
编辑:
如以下答案中所述,关闭所有内容并再次尝试成功构建扩展,但是使用 return PyModule_Create(&value);
仍然会崩溃。
PyModule_AddIntConstant(value, "DEFINED", DEFINED_VALUE);
是正确的(假设 DEFINED_VALUE
是一个 (C) long
).
结合最后的链接器错误(以及您正在编写代码然后进行测试,等等......)告诉我链接器无法编写新的 .pyd 文件(包含最新更改 - 包括 DEFINED
变量),因为它正被先前启动的 python.exe 使用导入您的模块的进程。
- 关闭 每个 运行ning 解释器导入你的模块(到 "unlock" WinUtils.cp36-win32.pyd)
- 构建(这一次,链接器将能够覆盖文件)
- 测试(运行 你的 Python 代码)
注意:您可以检查函数 return 值 ([Python]: int PyModule_AddIntConstant(PyObject *module, const char *name, long value))。
@EDIT0(关于 2nd 问题):
正如我在我的一条评论中所指出的那样,使用 PyModule_Create
(根据 [Python]: PyObject* PyModule_New(const char *name),您将得到 未定义的行为):
PyMODINIT_FUNC PyInit_utilities() {
PyObject *mod = PyModule_Create(&func);
PyModule_AddIntConstant(mod, "DEFINED", AF_INET);
return mod;
}