首页 > 解决方案 > 使用 ctypes 将结构从 C 传递到 Python

问题描述

我正在尝试将 astruct从 C 传递给 Python,但是当某些属性是char *

测试.h

typedef struct _FOO 
{
    int field1;
    char field2[5];
    int  whatever;
 } FOO, *PFOO;

 void CallPythonFunction(PFOO foo);

测试.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);
}

测试.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

主程序

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)

标签: pythoncctypes

解决方案


test.py中,类型field2不正确。 ctypes.c_char * 5是 C 的正确 ctypes 语法char[5]

同样在test.py,更改foo_view.field2.value为,foo_view.field2因为它不会是一个指针。如果没有该更改,Python 代码将抛出当前未被test.c代码处理的异常,并且它将在第一个print.

In main.c,sprintf(foo->field2, "hello");由于空终止符,将发生缓冲区溢出。


推荐阅读