This is the mail archive of the
libffi-discuss@sourceware.org
mailing list for the libffi project.
ffi_raw_closure with struct return types
- From: Marco Trudel <marco at mtsystems dot ch>
- To: libffi-discuss at sourceware dot org
- Date: Wed, 05 Oct 2011 13:13:48 +0200
- Subject: ffi_raw_closure with struct return types
Dear all
I can't manage to get struct return types to work with ffi_raw_closure.
I attached a file with 4 almost identical tiny testcases:
1. struct return, ffi_raw_closure: fails
2. struct return, ffi_closure: ok
3. double return, ffi_raw_closure: ok
4. double return, ffi_closure: ok
I tried with libffi-3.0.10 and latest git on a 32bit Linux.
Am I using libffi in an invalid way?
Maybe I'm setting the ffi_type fields (for the variable "struct_type")
wrong? It doesn't make a difference if I set the size to the struct
size, the alignment to 4 and the elements to two integers (so I omitted
that code to make the tests smaller).
Thanks
Marco
#include <stdio.h>
#include <stdlib.h>
#include <ffi.h>
struct point
{
int x;
int y;
};
// struct return, raw_ffi_closure: fails
void ffi_raw_callback_struct(ffi_cif *cif, void *ret, ffi_raw *args, void *callback_data)
{
struct point *p = ret;
printf("[1 struct-raw-ffi] 123x456 <-> ");
p->x = 123;
p->y = 456;
}
void test_struct_ret_raw_ffi()
{
struct point (*created_fp)();
struct point ret;
ffi_cif cif;
ffi_raw_closure *closure;
ffi_type struct_type;
struct_type.size = 1;
struct_type.type = FFI_TYPE_STRUCT;
if(!(closure = ffi_closure_alloc(sizeof(ffi_raw_closure), (void **)&created_fp))) exit(11);
if(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, &struct_type, 0) != FFI_OK) exit(12);
if(ffi_prep_raw_closure_loc(closure, &cif, &ffi_raw_callback_struct, 0, created_fp) != FFI_OK) exit(13);
ret = (*created_fp)();
printf("%dx%d\n", ret.x, ret.y);
ffi_closure_free(closure);
}
// struct return, ffi_closure: ok
void ffi_callback_struct(ffi_cif *cif, void *ret, void* args[], void *callback_data)
{
struct point *p = ret;
printf("[2 struct-ffi] 456x789 <-> ");
p->x = 456;
p->y = 789;
}
void test_struct_ret_ffi()
{
struct point (*created_fp)();
struct point ret;
ffi_cif cif;
ffi_closure *closure;
ffi_type struct_type;
struct_type.size = 1;
struct_type.type = FFI_TYPE_STRUCT;
if(!(closure = ffi_closure_alloc(sizeof(ffi_closure), (void **)&created_fp))) exit(21);
if(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, &struct_type, 0) != FFI_OK) exit(22);
if(ffi_prep_closure_loc(closure, &cif, &ffi_callback_struct, 0, created_fp) != FFI_OK) exit(23);
ret = (*created_fp)();
printf("%dx%d\n", ret.x, ret.y);
ffi_closure_free(closure);
}
// double return, raw_ffi_closure: ok
void ffi_raw_callback_double(ffi_cif *cif, void *ret, ffi_raw *args, void *callback_data)
{
double *p = ret;
printf("[3 double-raw-ffi] 123.456 <-> ");
*p = 123.456;
}
void test_double_ret_raw_ffi()
{
double (*created_fp)();
double ret;
ffi_cif cif;
ffi_raw_closure *closure;
if(!(closure = ffi_closure_alloc(sizeof(ffi_raw_closure), (void **)&created_fp))) exit(31);
if(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, &ffi_type_double, 0) != FFI_OK) exit(32);
if(ffi_prep_raw_closure_loc(closure, &cif, &ffi_raw_callback_double, 0, created_fp) != FFI_OK) exit(33);
ret = (*created_fp)();
printf("%.3lf\n", ret);
ffi_closure_free(closure);
}
// double return, ffi_closure: ok
void ffi_callback_double(ffi_cif *cif, void *ret, void* args[], void *callback_data)
{
double *p = ret;
printf("[4 double-ffi] 456.789 <-> ");
*p = 456.789;
}
void test_double_ret_ffi()
{
double (*created_fp)();
double ret;
ffi_cif cif;
ffi_closure *closure;
if(!(closure = ffi_closure_alloc(sizeof(ffi_closure), (void **)&created_fp))) exit(41);
if(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, &ffi_type_double, 0) != FFI_OK) exit(42);
if(ffi_prep_closure_loc(closure, &cif, &ffi_callback_double, 0, created_fp) != FFI_OK) exit(43);
ret = (*created_fp)();
printf("%.3lf\n", ret);
ffi_closure_free(closure);
}
// main
int main()
{
test_struct_ret_raw_ffi();
test_struct_ret_ffi();
test_double_ret_raw_ffi();
test_double_ret_ffi();
return 0;
}