使用 ctypes 将结构从 C 传递到 Python
Passing struct from C to Python with ctypes
我正在尝试将 struct
从 C 传递到 Python 但是当某些属性是 char *
时我遇到了问题
test.h
typedef struct _FOO
{
int field1;
char field2[5];
int whatever;
} FOO, *PFOO;
void CallPythonFunction(PFOO foo);
test.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
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
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;
}
我需要得到这个输出:
('foo.field1: ', 5)
('foo.field2: ', 'hello')
('foo.whatever: ', 3)
在test.py
中,field2
的类型不正确。 ctypes.c_char * 5
是 C char[5]
.
的正确 ctypes 语法
同样在 test.py
中,将 foo_view.field2.value
更改为 foo_view.field2
,因为它不是指针。如果不进行该更改,Python 代码将抛出 test.c
代码当前未处理的异常,并且它将在第一个 print
.
之后停止
在 main.c
中,sprintf(foo->field2, "hello");
将由于空终止符而发生缓冲区溢出。
我正在尝试将 struct
从 C 传递到 Python 但是当某些属性是 char *
test.h
typedef struct _FOO
{
int field1;
char field2[5];
int whatever;
} FOO, *PFOO;
void CallPythonFunction(PFOO foo);
test.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
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
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;
}
我需要得到这个输出:
('foo.field1: ', 5)
('foo.field2: ', 'hello')
('foo.whatever: ', 3)
在test.py
中,field2
的类型不正确。 ctypes.c_char * 5
是 C char[5]
.
同样在 test.py
中,将 foo_view.field2.value
更改为 foo_view.field2
,因为它不是指针。如果不进行该更改,Python 代码将抛出 test.c
代码当前未处理的异常,并且它将在第一个 print
.
在 main.c
中,sprintf(foo->field2, "hello");
将由于空终止符而发生缓冲区溢出。