libffi调用C函数时指针传递异常问题排查与解决
libffi调用C函数时指针参数变为NULL的问题解决
问题现象
使用libffi动态调用my_func函数时,调试确认arg_values数组中res的初始值正确,但进入my_func后,第三个参数res指针变为NULL,导致无法写入计算结果。
错误分析
- 参数个数配置错误:
ffi_prep_cif函数的第三个参数指定为2,但my_func实际包含3个参数(两个double类型、一个double*类型),libffi未正确处理第三个参数,导致参数传递异常。 - 指针参数传递方式错误:libffi要求所有参数都以参数的地址形式传入
arg_values数组。对于double*类型的参数,需要传递指向该指针的地址(即double**),原代码直接传入数组名res(退化为double*),不符合libffi的参数传递规则。
问题代码
#include <stdio.h> #include <stdlib.h> #include <ffi.h> unsigned my_func(double a, double b, double *res) { res[0] = a + b; res[1] = a - b; return 0; } int main(int argc, char *argv[]) { ffi_cif cif; ffi_type *arg_types[3] = { &ffi_type_double, &ffi_type_double, &ffi_type_pointer }; ffi_type *rettype = &ffi_type_uint; if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, rettype, arg_types) != FFI_OK) { fprintf(stderr, "ffi_prep_cif is not successful\n"); exit(EXIT_FAILURE); } double a = 3.0; double b = 2.0; double res[2] = {99.0, 15.0}; void *arg_values[3] = { &a, &b, res }; unsigned status; ffi_call(&cif, FFI_FN(my_func), &status, arg_values); printf("Function return status code %u\n", status); printf("Values in res array: \n"); printf("[0] = %f\n", res[0]); printf("[1] = %f\n", res[1]); return 0; }
调试信息
(gdb) p ((double *) arg_values[2])[0] $1 = 99 (gdb) p ((double *) arg_values[2])[1] $2 = 15
Breakpoint 2, my_func (a=3, b=2, res=0x0) at test_ffi.c:6 6 res[0] = a + b;
修复后代码
#include <stdio.h> #include <stdlib.h> #include <ffi.h> unsigned my_func(double a, double b, double *res) { res[0] = a + b; res[1] = a - b; return 0; } int main(int argc, char *argv[]) { ffi_cif cif; ffi_type *arg_types[3] = { &ffi_type_double, &ffi_type_double, &ffi_type_pointer }; ffi_type *rettype = &ffi_type_uint; if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, rettype, arg_types) != FFI_OK) { fprintf(stderr, "ffi_prep_cif is not successful\n"); exit(EXIT_FAILURE); } double a = 3.0; double b = 2.0; double res[2] = {99.0, 15.0}; double *p_res = res; void *arg_values[3] = { &a, &b, // res &p_res }; unsigned status; ffi_call(&cif, FFI_FN(my_func), &status, arg_values); printf("Function return status code %u\n", status); printf("Values in res array: \n"); printf("[0] = %f\n", res[0]); printf("[1] = %f\n", res[1]); return 0; }
内容的提问来源于stack exchange,提问作者Dmitry Kabanov
相关产品推荐
相关产品推荐

