Reputation: 14831
I have a function implemented in C that translates a string to an array of a defined enum
. The C code looks like this:
Header file (describes the enum
):
/* File `asdf.h` */
enum translation {
ONE,
ANOTHER,
FINISH,
};
void translate(char *origin, enum translation *destination);
The source file (implements the function that makes the translation):
/* File `asdf.c` */
#include "asdf.h"
void translate(char *origin, enum translation *destination)
{
while (1) {
if (*origin == 'F')
break;
if (*origin == 'O')
*destination++ = ONE;
if (*origin == 'A')
*destination++ = ANOTHER;
origin++;
}
*destination = FINISH;
}
Now I would like to be able to call this function from Python, using CFFI, and being able to check the correct values of the output array (translation). How could I do that?
I have tried to compile the module first and then create the variables and call the function this way, but did not manage to make it work:
# File `cffienum.py`
from pathlib import Path
from cffi import FFI
ffibuilder = FFI()
ffibuilder.cdef(Path('asdf.h').read_text())
ffibuilder.set_source(
'_asdf', # name of the output C extension
'#include "asdf.h"',
sources=['asdf.c']) # includes asdf.c as additional sources
ffibuilder.compile()
if __name__ == '__main__':
from _asdf.lib import translate
ffi = FFI()
ffi.cdef(Path('asdf.h').read_text())
c = ffi.dlopen('c')
source = ffi.new('char source[]', b'OAF')
destination = ffi.new('enum translation destination[10]')
translate(source, destination)
print(source, destination)
This is the error I get:
$ pipenv run python cffienum.py
Traceback (most recent call last):
File "cffienum.py", line 24, in <module>
translate(source, destination)
TypeError: initializer for ctype 'enum translation *' must be a pointer to same type, not cdata 'enum translation[10]'
First contact with CFFI and not an experienced C programmer, so I bet I am doing many things wrong here.
Note that if instead of:
void translate(char *origin, enum translation *destination)
I use:
void translate(char *origin, char *destination)
Or:
void translate(char *origin, uint8_t *destination)
It works just fine. So there is something I must be missing when using enum translation *
...
Upvotes: 1
Views: 504
Reputation: 12955
You must use the ffi object from the _adsl
module:
from _asdf import ffi
instead of making a new FFI instance and redefining an unrelated type enum translation
that happens to be identical.
Upvotes: 2