[英]Passing struct from C to Python with ctypes
I'm trying to pass a struct
from C to Python but I've problems when some attribute is a char *
我正在尝试将struct
从 C 传递给 Python 但是当某些属性是char *
test.h测试.h
typedef struct _FOO
{
int field1;
char field2[5];
int whatever;
} FOO, *PFOO;
void CallPythonFunction(PFOO foo);
test.c测试.c
PyObject *module_name, *plugin, *PyTargetFunction, *ppresult, *pargs;
void CallPythonFunction(PFOO foo)
{
// Set PYTHONPATH TO working directory
setenv("PYTHONPATH",dir_python_modules,1);
// Initialize the Python Interpreter
Py_Initialize();
module_name = PyString_FromString((char*)"test");
// Load the module object
if ((plugin = PyImport_Import(module_name)) == NULL) {
PyErr_Print();
printf("Error: PyImport_Import\n");
return -1;
}
PyTargetFunction = PyObject_GetAttrString(plugin, (char*)"some_function");
pargs = PyTuple_Pack(1
//, PyLong_FromUnsignedLong((unsigned int) validacion)
, PyLong_FromVoidPtr(foo)
);
ppresult = PyObject_CallObject(PyTargetFunction, pargs);
}
test.py测试.py
import ctypes
POINTER = ctypes.POINTER
class _PyFoo(ctypes.Structure):
_fields_ = [
('field1', ctypes.c_int),
('field2', ctypes.c_char_p),
#('field2', POINTER(ctypes.c_char), # not work either
('whatever', ctypes.c_int)
]
def some_function(foo):
foo_view = _PyFoo.from_address(foo)
print("foo.field1: ", foo_view.field1)
print("foo.field2: ", foo_view.field2.value)
print("foo.whatever: ", foo_view.whatever)
pass
main.c main.c
int main(int argc, char *argv[])
{
PFOO foo = malloc(sizeof(FOO));
foo->field1 = 5;
sprintf(foo->field2, "hello");
foo->whatever = 3;
CallPythonFunction(foo);
return 0;
}
I need get this output:我需要得到这个 output:
('foo.field1: ', 5)
('foo.field2: ', 'hello')
('foo.whatever: ', 3)
In test.py
, the type of field2
is incorrect.在test.py
中, field2
的类型不正确。 ctypes.c_char * 5
is the correct ctypes syntax for a C char[5]
. ctypes.c_char * 5
是 C char[5]
的正确 ctypes 语法。
Also in test.py
, change foo_view.field2.value
to foo_view.field2
since it will not be a pointer.同样在test.py
中,将foo_view.field2.value
更改为foo_view.field2
因为它不是指针。 Without that change, the Python code will throw an exception that isn't currently handled by the test.c
code and it will just stop after the first print
.如果没有该更改, Python 代码将引发test.c
代码当前未处理的异常,并且它将在第一次print
之后停止。
In main.c
, sprintf(foo->field2, "hello");
在main.c
, sprintf(foo->field2, "hello");
is going to have a buffer overflow because of the null terminator.由于 null 终结器,将会发生缓冲区溢出。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.