简体   繁体   English

使用 ctypes 将结构从 C 传递到 Python

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM