【发布时间】:2014-04-29 23:51:22
【问题描述】:
这对你来说很奇怪:我一直在遵循this tutorial 的框架,试图编写一个 Python 模块,该模块将返回一个包含 C 函数结果的结构。
C 结构体是这样定义的:
typedef struct my_struct
{
// Initialize refcount and pointer to type objects (no ';' )
PyObject_HEAD
// Components of the structure go here.
uint32_t width; // unsigned long
uint32_t height; // unsigned long
uint8_t numcomps; // unsigned char
uint8_t bitspercomp; // unsigned char
uint8_t bytespercomp; // unsighed char
uint32_t total_data_len; // unsigned long
int data;
} my_struct;
问题是在 Python 级别访问时,结构的成员似乎在内存中重叠!表格输入:
my_struct.My_Struct(unsigned_long 1, unsigned_long 2, unsigned_char 3, unsigned_char 4, unsigned_char 5, unsigned_long 6, int 7)
存储在返回位置的值明显重叠。当它们表示为十六进制值时,最容易看出这一点:
In [1]: import my_struct as ms
In [2]: op = ms.My_Struct(1,2,3,4,5,6,7)
In [3]: myfi.width
Out[3]: 8589934593L ***should be "1"***
In [4]: "%x"%op.width
Out[4]: '200000001'
In [5]: "%x"%op.height
Out[5]: '5040300000002'
In [6]: "%x"%op.numcomps
Out[6]: '3'
In [7]: "%x"%op.bitspercomp
Out[7]: '4'
In [8]: "%x"%op.bytespercomp
Out[8]: '5'
In [9]: "%x"%op.total_data_len
Out[9]: '700000006'
In [10]: "%x"%op.data
Out[10]: '7'
输入参数的分配发生在一个调用方法Py_Arg_ParseTupleAndKeywords()的init函数中:
static int
my_struct_init(my_struct *self, PyObject *args, PyObject *kwds)
{
static char *kwlist[] =
{"width","height","numcomps","bitspercomp","bytespercomp","total_data_len","data", NULL};
// Increase reference count before parsing
Py_INCREF(self);
if (! PyArg_ParseTupleAndKeywords(args, kwds, "kkbbbki"
, kwlist, &self->width, &self->height,
&self->numcomps, &self->bitspercomp,
&self->bytespercomp,
&self->total_data_len, &self->data))
return -1;
return 0;
};
一直找不到类似的问题,请帮忙!
脚本的其余部分遵循示例的格式。有一个“新”函数将每个结构成员值设置为零,还有一个析构函数。可能相关的是模块成员定义:
static PyMemberDef my_struct_members[] = {
/*member name, type, offset, access flags, documentation string*/
{"width", T_ULONG, offsetof(my_struct, width), 0,
"words and such."},
{"height", T_ULONG, offsetof(my_struct, height), 0,
"words and such."},
{"numcomps", T_UBYTE, offsetof(my_struct, numcomps), 0,
"words and such."},
{"bitspercomp", T_UBYTE, offsetof(my_struct, bitspercomp), 0,
"words and such."},
{"bytespercomp", T_UBYTE, offsetof(my_struct, bytespercomp), 0,
"words and such."},
{"total_data_len", T_ULONG, offsetof(my_struct, total_data_len), 0,
"words and such."},
{"data", T_UINT, offsetof(my_struct, data), 0,
"words and such."},
{NULL} /* Sentinel */
};
【问题讨论】:
-
经过进一步研究,发现
my_struct_members中将T_ULONG类型替换为T_UINT时不会出现这种行为。 T_ULONG 行为仍然让我感到困惑。
标签: memory-management struct python-module python-c-api