Issue #127 resolved

Function pointers + unions by value

vdcrim
created an issue

As already documented, libffi doesn't support returning or passing as an argument unions by value. Attempting to do such from Python code will cause a NotImplementedError, which is fine. However, this exception can also happen on verify for function pointers:

import cffi

cdef_str = r"""

union Data{int a; float b;};

void (*function_ptr)(union Data);

"""

ffi = cffi.FFI()
ffi.cdef(cdef_str)
lib = ffi.verify(cdef_str)
NotImplementedError: <void(*)(union Data)>: ctype 'union Data' not supported as argument or return value

I guess this is not intended. Here is a demo of my particular case, in which some of the functions on the API struct return or have as parameters unions by value:

import cffi

cdef_str = r"""

typedef union Data{
    int a;
    float b;
}Data;

typedef struct API{
    void (*api_function_ptr)(Data);
}API;

API* load_library();
void free_library(API*);

API *api; // to be initialized with load_library

void api_function(Data *s); // wrapper

"""

verify_str = r"""

typedef union Data{
    int a;
    float b;
}Data;

typedef struct API{
    void (*api_function_ptr)(Data);
}API;

API* load_library(){ // LoadLibrary + GetProcAddress
    API *api;
    return api;
}
void free_library(API* api){}

API *api;

void api_function(Data *data){
    api->api_function_ptr(*data);
}

"""

ffi = cffi.FFI()
ffi.cdef(cdef_str)
lib = ffi.verify(verify_str)
lib.api = lib.load_library()

Comments (3)

  1. Armin Rigo

    Thanks, I'll look. In the meantime, since anyway you cannot call the api_function_ptr directly, is there a reason it is declared in the cdef at all? It seems that you could simply say there: typedef struct API{ ...; } API;

  2. vdcrim reporter

    Only a few of the functions have unions as return or parameters. But you're right, I can write wrappers for all of them.

  3. Log in to comment