简体   繁体   中英

Pass array pointer to C function with struct return type using Python's ctypes

I have a C function -

ERROR foo(int32_t* toptr, int64_t length) { 
    for (int32_t i = 0;  i < length;  i++) { 
        toptr[i] = i; 
    } 
    return bar(); 
}

ERROR and bar are defined as -

#define ERROR struct Error


struct __attribute__((visibility("default"))) Error {
    const char* x;
    int64_t hu;
};

inline struct Error
bar() {
 struct Error bla;
 bla.x = nullptr;
 bla.hu = 0;
 return bla;
};

How do I represent this struct using ctypes? According to https://stackoverflow.com/a/38663141/4647107 , I should redeclare it, but my struct has a slightly different format than in that answer.

I can successfully load the function using ctypes -

>>> import ctypes
>>> test = ctypes.CDLL("dummy.so")
>>> test.foo
<_FuncPtr object at 0x7f6cec73b7c0>

If I assign a placeholder return type to foo -

test.foo.restype = ctypes.c_bool

and then try to use it (based on https://stackoverflow.com/a/4145859/4647107 ) -

test.foo.argtypes = ctypes.POINTER(ctypes.c_int32), ctypes.c_int64
outarray = [1, 2, 3, 4, 5]
test.foo((ctypes.c_int32 * len(outarray))(*outarray), len(outarray))

I get a Segmentation fault (core dumped) error.

struct Error wasn't provided. Below is an example of declaring the structure and using it.

test.c:

#include <stdint.h>

typedef struct Error
{
    const char* x;
    int64_t hu;
} ERROR;

ERROR bar() {
    ERROR bla;
    bla.x = NULL;
    bla.hu = 5;
    return bla;
}

__declspec(dllexport)
ERROR foo(int32_t* toptr, int64_t length) {
    for (int32_t i = 0;  i < length;  i++) {
        toptr[i] = i;
    }
    return bar();
}

test.py:

from ctypes import *

class Error(Structure):
    _fields_ = [('x',c_char_p),
                ('hu',c_int64)]

dll = CDLL('./test')
dll.foo.argtypes = POINTER(c_int32),c_int64
dll.foo.restype = Error

outarray = (c_int32 * 5)()
err = dll.foo(outarray,len(outarray))
print(err.x)
print(err.hu)
print(list(outarray))

Output:

None
5
[0, 1, 2, 3, 4]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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