Python C-API…如何在C中编写python代码
问题描述:
我有以下python代码...,并希望将其编写为... Python - C - API
I have the following python code… and want to write this Code in… Python-C-API
from enum import Enum
class MqWaitOnEventE(Enum):
NO = 0
ONCE = 1
FOREVER = 2
感谢您的帮助.
第一方法
// enum definition
PyObject *enumModO=NULL, *enumDictO=NULL, *intEnumO=NULL;
LngErrorCheckN(enumModO = PyImport_ImportModule("enum"));
LngErrorCheckN(enumDictO = PyModule_GetDict(enumModO));
LngErrorCheckN(intEnumO = PyDict_GetItemString(enumDictO,"IntEnum"));
// get 'MqWaitOnEventE '
PyObject *dictMqWaitOnEventE = NULL, *result=NULL, *base=NULL;
LngErrorCheckN(dictMqWaitOnEventE = PyDict_New());
LngErrorCheck(PyDict_SetItemString (dict, "__module__", PyUnicode_FromString("pymsgque")));
LngErrorCheck(PyDict_SetItemString (dict, "NO", OT_NEW_INT_OBJ(MQ_WAIT_NO)));
LngErrorCheck(PyDict_SetItemString (dict, "ONCE", OT_NEW_INT_OBJ(MQ_WAIT_ONCE)));
LngErrorCheck(PyDict_SetItemString (dict, "FOREVER", OT_NEW_INT_OBJ(MQ_WAIT_FOREVER)));
LngErrorCheckN(base = PyTuple_Pack(1, intEnumO));
LngErrorCheckN(result = PyObject_CallFunction((PyObject *)&PyType_Type, "sOO","MqWaitOnEventE", base, dictMqWaitOnEventE));
以以下错误结束...
end with following error…
Traceback (most recent call last):
File "…/MyServer.py", line 14, in <module>
import pymsgque
File "…/python3.7/enum.py", line 151, in __new__
enum_members = {k: classdict[k] for k in classdict._member_names}
AttributeError: 'dict' object has no attribute '_member_names'
这是什么? …python是否需要我的内部成员?
what is this? … does python require som internals from me ?
答
这是C模块初始化文件中枚举的类型安全的解决方案……
This is the type-safe solution for a enum in C-Module initialization file…
-
MqBuffer…
是我的字符串缓冲区类 -
NS(…)
是用于创建唯一命名空间的宏……我将其用于所有c-extern对象
-
MqBuffer…
is my string buffer class -
NS(…)
is a macro to create a unique namespace… I use this for all c-extern objects .
示例将在模块名称空间中创建新的 MqSlaveE 类.
the example will create the new MqSlaveE class in the module namespace.
PyObject* m = PyModule_Create(&ModuleDef);
...
MQ_BUF buf = MqBufferCreate(1000);
MqBufferAppendC(buf,"from enum import IntEnum\n");
MqBufferAppendC(buf,"class MqSlaveE(IntEnum):\n");
MqBufferAppendV(buf," LOOPBACK = %i\n", MQ_SLAVE_LOOPBACK);
MqBufferAppendV(buf," OTHER = %i\n", MQ_SLAVE_OTHER);
MqBufferAppendV(buf," FILTER = %i\n", MQ_SLAVE_FILTER);
MqBufferAppendV(buf," MASTER = %i\n", MQ_SLAVE_MASTER);
MqBufferAppendV(buf," USER = %i\n", MQ_SLAVE_USER);
PyObject *g, *dl, *dg, *v;
MQ_CST script = MqBufferGetC_e(buf);
g = PyImport_AddModule("__main__");
dg = PyModule_GetDict(g);
dl = PyModule_GetDict(m);
LngErrorCheckN(v = PyRun_String(script, Py_file_input, dg, dl));
Py_DECREF(v);
NS(MqSlaveE) = PyDict_GetItemString(dl,"MqSlaveE");
MqBufferDelete(&buf);
return m;
要检查对象并提取我使用proc的值……
to check the object and extract the value I use a proc…
enum MqErrorE NS(Get_Enum_FromObj) (PyObject *enumT, PyObject *enumE, MQ_INT *ret) {
if (!PyObject_IsInstance(enumE, enumT)) {
PyErr_Format(PyExc_TypeError,
"input_enum_type = '%s' is not the required_enum_type = '%s'",
Py_TYPE(enumE)->tp_name, ((PyTypeObject*)enumT)->tp_name
);
return MQ_ERROR;
}
return PyObj_AsINT(enumE,ret);
}