编译程序时,发现测试用例过不去,抽象出其中的测试用例。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ffi.h>
#include <glib.h>
#include <glib-object.h>
#include <glib/gprintf.h>
#include <girepository.h>
#include <gmodule.h>
typedef enum _cairo_status{
CAIRO_STATUS_SUCCESS = 0,
CAIRO_STATUS_NO_MEMORY,
CAIRO_STATUS_INVALID_RESTORE,
CAIRO_STATUS_INVALID_POP_GROUP
} cairo_status_t;
cairo_status_t test_func(int m, int n)
{
return CAIRO_STATUS_SUCCESS;
}
void test_ffi_call (void) {
GIArgument retval;
void* func_addr = &test_func;
int nargs = 2;
ffi_type **ffi_arg_types = alloca(sizeof(ffi_type *) *nargs);
ffi_arg_types[0] = &ffi_type_sint;
ffi_arg_types[1] = &ffi_type_sint;
void **ffi_args = alloca(sizeof(void *) *nargs);
void *ffi_arg_ptr = alloca(ffi_arg_types[0]->size);
int *arg1 = ffi_arg_ptr;
*arg1 = 4;
ffi_args[0] = ffi_arg_ptr;
void *ffi_arg_ptr2 = alloca(ffi_arg_types[1]->size);
int *arg2 = ffi_arg_ptr2;
*arg2 = 5;
ffi_args[1] = ffi_arg_ptr2;
ffi_cif cif;
ffi_type *ffi_ret_type = &ffi_type_sint32;
//ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs, ffi_type *rtype, ffi_type **atypes);
ffi_status status = ffi_prep_cif(&cif, FFI_DEFAULT_ABI, (unsigned int)nargs, ffi_ret_type, ffi_arg_types);
if (status == FFI_OK) {
union { GIArgument arg; ffi_sarg i; } *uu = (gpointer)&retval;
printf("0--->%lx, %p.\n", uu->i, &retval);
uu->i = 0x12cf702d0;
uu = (gpointer)&retval;
printf("1--->%lx, %p.\n", uu->i, &retval);
//ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue);
ffi_call(&cif, func_addr, &retval, ffi_args);
uu = (gpointer)&retval;
printf("2--->%lx, %p.\n", uu->i, &retval);
}
}
int main (void)
{
test_ffi_call();
return 0;
}
编译:
~$ gcc test_ffi.c -o test -fpermissive -w -lffi -I/usr/include/gobject-introspection-1.0/ -I/usr/include/glib-2.0/ -I/usr/lib/loongarch64-linux-gnu/glib-2.0/include/