gpt4 book ai didi

python-2.7 - 在 Python C 扩展中使用新类型

转载 作者:行者123 更新时间:2023-12-05 05:27:19 25 4
gpt4 key购买 nike

我已经编写代码在 Python C 扩展 (MyStatus) 中定义一个新类型。我编写了 C 代码来定义分配、解除分配等,如 page 中所述.

我能够编译模块并从 python 中使用它。

现在我正尝试在另一个 Python C 扩展 (TestStatus) 中使用这个新类型我的要求是我只需要一个 .so 为此。我不想直接从 Python 代码使用 MyStatus。我将只在我的代码中导入 TestStatus,我想从为 TestStatus 编写的 C 扩展中初始化 MyStatus。

我已经为 TestStatus 编写了这样的代码

static PyObject * TestStatus_checkPyObject *self, PyObject *args)
{
PyObject * mystatus = NULL;
const char *command;

/* Call the class object. */
mystatus = PyObject_CallObject((PyObject *) &MyStatusType, NULL);

return mystatus;
}

PyMODINIT_FUNC initTestStatus(void)
{
(void) Py_InitModule("TestStatus", TestMethods);

initMyStatus();//This is available in the C code written for MyStatus
}

我能够像我在代码中提到的那样创建 so。但我坚持为 MyStatus 设置变量,它是一个整数和 char*(PyObject*)有人可以对此有所说明,例如我的方法是否正确以及如何使用参数从 TestStatus 初始化和使用 MyStatus。

I am trying this with Python 2.6.6 on Rhel 6.3

在 MyStatus 中我有 2 个变量

typedef struct {
PyObject_HEAD
int mStatus;
PyObject *mErrorString;
} MyStatus;

我需要从 TestStatus 初始化它。

最佳答案

Python C 扩展应该提供 C-API从其他 C 模块中使用。所以在你的情况下,你的 MyStatus.h 应该有一些东西,比如

/* Header file for MyStatus module */

#ifndef MyStatus_MODULE_H
#define MyStatus_MODULE_H
#ifdef __cplusplus
extern "C" {
#endif

typedef struct {
PyObject_HEAD
int mStatus;
PyObject *mErrorString;
} MyStatus;

#define MyStatus_Type_NUM 0

#define MyStatus_New_NUM 1
#define MyStatus_New_RETURN MyStatus *
#define MyStatus_New_PROTO (int mStatus, PyObject *mErrorString)

/* Total number of C API pointers */
#define MyStatus_API_pointers 2

#ifdef MyStatus_MODULE
/* do nothing for this minimal example */
#else

static void **MyStatus_API;

#define MyStatus_Type (*(PyTypeObject *)(\
MyStatus_API[MyStatus_Type_NUM]))

#define MyStatus_New \
(*(MyStatus_New_RETURN (*)MyStatus_New_PROTO) \
MyStatus_API[MyStatus_New_NUM])

static int import_MyStatus(void)
{
MyStatus_API = (void **)PyCapsule_Import("MyStatus._C_API", 0);
return (MyStatus_API != NULL) ? 0 : -1;
}
#endif /* !defined(MyStatus_MODULE) */
#ifdef __cplusplus
}
#endif
#endif /* !defined(MyStatus_MODULE_H) */

并定义类似的东西

static Py MyStatus *
PyMyStatus_New(int mStatus, PyObject *mErrorString){
MyStatus *self;
self = (MyStatus *)MyStatusType.tp_alloc(&MyStatusType, 0);
self->mStatus = mStatus;
Py_INCREF(mErrorString); // in case you don't want to steal a reference
self->mErrorString = mErrorString;
if (!self->mErrorString){
Py_DECREF(self);
return NULL;
}
return self;
}

#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
#define PyMODINIT_FUNC void
#endif PyMODINIT_FUNC initMyStatus(void){
PyObject *m = Py_InitModule3("MyStatus", methods, "");
static void *MyStatus_API[MyStatus_API_pointers];

MyStatus_API[MyStatus_Type_NUM] = (void *)&MyStatusType;
MyStatus_API[MyStatus_New_NUM] = (void *)MyStatus_New;

PyObject *c_api_object = PyCapsule_New((void *)MyStatus_API, "MyStatus._C_API", NULL);
if (c_api_object != NULL) PyModule_AddObject(m, "_C_API", c_api_object); }

MyStauts.c 中。此外,它是非常方便的定义宏如

PyMyStatus_SET_MSTATUS(self, mStatus)
PyMyStatus_GET_MSTATUS(self)
PyMyStatus_SET_mErrorString(self, mErrorString)
PyMyStatus_GET_mErrorString(self)

以便以后能够更改 MyStatus 的底层结构并处理引用计数。

如果您不想这样做,您始终可以直接初始化和修改 MyStatus 对象,如上例中的 MyStatus_New 函数所示。

TestStatus.c 中最后导入C-API。

PyMODINIT_FUNC initTestStatus(void){
import_MyStatus();
Py_InitModule3("TestStatus", methods, "");

}

现在您将能够使用 MyStatus_NewMyStatusType

关于python-2.7 - 在 Python C 扩展中使用新类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20137358/

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