This is the mail archive of the libffi-discuss@sourceware.org mailing list for the libffi project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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;
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]