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.