Hoe kan ik een array van structs in python doorgeven aan mijn c library? Ik heb me gebasseerd op de tweede oplossing https://stackoverflow.com...n-ctypes-array-of-structs maar krijg nog een foutmelding.
foo.h
foo.c
test_run.py
Dit geeft mij de foutmelding op de lijn lib.test_print(..)
Een klein bijvraagje. Mij eerste fout was
foo.h
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| struct si16s { int16_t si; int8_t scale; }; struct covar_si { struct si16s matrix[6]; int8_t min_scale[3]; }; void test_print(const struct covar_si *val); |
foo.c
C:
1
2
3
4
5
6
7
8
9
10
11
| void test_print(const struct covar_si *val) { uint8_t i = 0; for (; i < 6; ++i) printf("%i / 2 ^ %i\n", val -> matrix[i].si, val -> matrix[i].scale); for (i = 0; i < 3; ++i) printf("%i\t", val -> min_scale[i]); printf("\n"); } |
test_run.py
Python:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
| lib = ct.cdll.LoadLibrary(LIB_PATH) POINTER = ct.POINTER class SI16S(ct.Structure): _fields_ = [('si', ct.c_int16), ('scale', ct.c_int8)] COVAR_LENGTH = int(N_TOT_FEAT * (N_TOT_FEAT + 1) / 2) COVAR_ARR = SI16S * COVAR_LENGTH class COVAR_SI(ct.Structure): _fields_ = [('matrix', POINTER(SI16S)), ('min_scale', POINTER(ct.c_int8))] def __init__(self): elems = (SI16S * COVAR_LENGTH)() self.matrix = ct.cast(elems, POINTER(SI16S)) elems = (ct.c_int8 * N_TOT_FEAT)() self.min_scale = ct.cast(elems, POINTER(ct.c_int8)) for i in range(COVAR_LENGTH): self.matrix[i] = SI16S(i, 2) for i in range(N_TOT_FEAT): self.min_scale[i] = 3 |
Python:
1
2
3
4
5
6
7
8
| def main(): test_int = COVAR_SI() lib.test_print(POINTER(test_int)) if __name__ == "__main__": main() |
Dit geeft mij de foutmelding op de lijn lib.test_print(..)
Wat doe ik verkeerd? test_int is toch een COVAR_SI class object en dus een ctypes type? Het lukt mij om een SI16S door te geven naar mijn C library om hem te printen. De COVAR_SI lukt dan weer niet.Traceback (most recent call last):
File "test_run.py", line 21, in <module>
main()
File "test_run.py", line 17, in main
lib.test_print(POINTER(test_int))
TypeError: must be a ctypes type
Een klein bijvraagje. Mij eerste fout was
schrijven alselems = (SI16S * COVAR_LENGTH)()
Dus zonder haakjes op het einde, had ze niet gezien. Wat doen deze haakjes?elems = (SI16S * COVAR_LENGHT)