Python 2.7 在PythonC扩展中使用新类型

Python 2.7 在PythonC扩展中使用新类型,python-2.7,python-c-extension,Python 2.7,Python C Extension,我已经编写了用Python C扩展(MyStatus)定义新类型的代码。 我编写了C代码来定义本文提到的分配、解除分配等 我能够编译模块并从python中使用它 现在我尝试在另一个Python C扩展(TestStatus)中使用这种新类型 我的要求是我只需要一个。所以对于这个。 我不想直接从Python代码中使用MyStatus。 我将只在代码中导入TestStatus,我想从为TestStatus编写的C扩展中初始化MyStatus 我已经为TestStatus编写了这样的代码 static

我已经编写了用Python C扩展(MyStatus)定义新类型的代码。 我编写了C代码来定义本文提到的分配、解除分配等

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

现在我尝试在另一个Python C扩展(TestStatus)中使用这种新类型 我的要求是我只需要一个。所以对于这个。 我不想直接从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
    }
我能够像我在代码中提到的那样创建。 但是我一直在为MyStatus设置变量,它是一个整数和char*(PyObject*) 有没有人能解释一下,比如我的方法是否正确,以及如何从TestStatus初始化并使用MyStatus和参数

我正在RHEL6.3上使用Python2.6.6进行尝试

在MyStatus中,我有两个变量

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

我需要从TestStatus对其进行初始化。

Python C扩展应该提供一个可从其他C模块中使用的。所以在你的例子中,sou应该在你的
MyStatus.h
中有类似的东西

MyStatus模块的头文件*/ #ifndef MyStatus_模块 #定义MyStatus_模块 #ifdef_uucplusplus 外部“C”{ #恩迪夫 类型定义结构{ 皮尤头 int mStatus; PyObject*mErrorString; }MyStatus; #定义MyStatus\u类型\u数量0 #定义MyStatus\u New\u NUM 1 #定义MyStatus\u新建\u返回MyStatus* #定义MyStatus_New_PROTO(int-mStatus,PyObject*mErrorString) /*C API指针的总数*/ #定义MyStatus\u API\u指针2 #ifdef MyStatus_模块 /*对于这个最小的示例,请不要执行任何操作*/ #否则 静态void**MyStatus\u API; #定义MyStatus_类型(*(PyTypeObject*))(\ MyStatus_API[MyStatus_类型_数量]) #定义MyStatus_New\ (*(MyStatus_New_RETURN(*)MyStatus_New_PROTO)\ MyStatus_API[MyStatus_New_NUM]) 静态int导入_MyStatus(void) { MyStatus_API=(void**)PyCapsule_导入(“MyStatus._C_API”,0); 返回值(MyStatus_API!=NULL)?0:-1; } #endif/*!已定义(MyStatus_模块)*/ #ifdef_uucplusplus } #恩迪夫 #endif/*!已定义(MyStatus_模块_H)*/ 定义如下

静态Py MyStatus*
PyMyStatus_New(int-mStatus,PyObject*mErrorString){
自我状态;
self=(MyStatus*)MyStatusType.tp_alloc(&MyStatusType,0);
self->mStatus=mStatus;
Py_INCREF(mErrorString);//以防您不想窃取引用
self->mErrorString=mErrorString;
如果(!self->mErrorString){
Py_DECREF(self);
返回NULL;
}
回归自我;
}
#用于DLL导入/导出的ifndef PyMODINIT_FUNC/*声明*/
#定义PyMODINIT_FUNC void
#endif pymodini_FUNC initMyStatus(无效){
PyObject*m=Py_InitModule3(“MyStatus”,methods,”);
静态void*MyStatus_API[MyStatus_API_指针];
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.\u c_api”,NULL);
如果(c_api_object!=NULL)PyModule_AddObject(m,“_c_api”,c_api_object);}
MyStauts.c
中。此外,这是非常方便的 定义宏,如

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

如果您不想这样做,您总是可以直接初始化和修改
MyStatus
对象,如上面的
MyStatus\u New
函数示例所示

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


现在,您可以使用
MyStatus\u New
MyStatusType

设置“变量”,哪些变量?你能说得更具体些吗,那会有帮助的。为什么只要求在
上有一个
文件?如果你把两个模块的代码放在一个文件中,它会工作吗很抱歉,我没有退出,因此很难解释这个问题。我编辑了这篇文章来添加有关变量的信息。我将此代码作为MyStatus的一部分。但我的疑问是,我应该如何从TestStatus中调用它。正如你所看到的,我正在调用initMyStatus。但是在TestStatus的方法中,我应该初始化MyStatus的一个对象,并使用errorstring和status初始化它。这就是我所在的地方,斯图克,我明白了。我认为问题在于您试图调用
initMyStatus()
initTestStatus
中。您需要调用
import_MyStatus()MyStatus
模块中定义的code>来导入C-API。然后,您可以在
TestStatus
中调用
MyStatus
中的函数,如果通过C-API导出,则可以使用该类型。您将尝试此操作并让您知道…感谢您的输入您的尝试成功了吗?您应该能够将所有内容放在一个文件中,
MyStatus
类型和
TestStatus
类型的定义。在这种情况下,您甚至不需要显式导入C-API。但是,您创建MyStatus对象并与之交互的方式应该保持不变,例如通过
PyMyStatus\u New
。我不明白的是,如果您不想将MyStatus暴露于python,为什么它应该是python类型。在这种情况下,我将只使用普通的C结构和函数,而不是处理复杂的PythonC-API。
PyMyStatus_SET_MSTATUS(self, mStatus)
PyMyStatus_GET_MSTATUS(self)
PyMyStatus_SET_mErrorString(self, mErrorString)
PyMyStatus_GET_mErrorString(self)
PyMODINIT_FUNC initTestStatus(void){
    import_MyStatus();
    Py_InitModule3("TestStatus", methods, "");

}