You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 16:14:55