FFI:如何将C中的指针传递给C函数?

y1aodyip  于 2023-10-16  发布在  其他
关注(0)|答案(1)|浏览(130)

我正在努力使用libffi(函数外部接口库),可能是由于缺乏C经验。下面的程序使用libffi动态调用函数my_func

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

当我调试程序时,似乎所有的arg_values都设置正确:

(gdb) p ((double *) arg_values[2])[0]
$1 = 99
(gdb) p ((double *) arg_values[2])[1]
$2 = 15

您可以在上面看到,arg_values第三个值被正确地设置为res数组。
然而,当我在函数my_func中时,第三个参数(res数组)变成了NULL

Breakpoint 2, my_func (a=3, b=2, res=0x0) at test_ffi.c:6
6           res[0] = a + b;

我真的不明白这里有什么问题。有人能给我解释一下,为什么会发生这种情况,以及如何解决?谢谢你,谢谢!

更新

感谢@selbie的评论,以下修改后的程序可以工作(注意,我们获得了指向数组res的第二个指针,并将其地址传递给FFI):

#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;
}
628mspwn

628mspwn1#

这不应该是:

if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, rettype, arg_types) != FFI_OK)

是这样的:

if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, rettype, arg_types) != FFI_OK)

假设你调用了一个需要三个参数的函数,但只初始化了ffi的东西,让它需要两个参数,那么一个参数丢失就不足为奇了。

相关问题