我将在此处发布与 duplicated question 发布的相同答案,但您应该看看那里的讨论:
什么是 libffi?
有些程序在编译时可能不知道要传递给函数的参数。例如,解释器可能会在运行时被告知用于调用给定函数的参数的数量和类型。 'libffi' 可用于此类程序,以提供从解释程序到编译代码的桥梁。
“libffi”库为各种调用约定提供了可移植的高级编程接口。这允许程序员在运行时调用由调用接口描述指定的任何函数。
FFI 代表外部功能接口。外来函数接口是接口的通称,它允许用一种语言编写的代码调用用另一种语言编写的代码。 “libffi”库实际上只提供了功能齐全的外来函数接口的最低、机器相关层。 “libffi”之上必须存在一个层,用于处理在两种语言之间传递的值的类型转换。
‘libffi’假设你有一个指向你想要调用的函数的指针,并且你知道要传递它的参数的数量和类型,以及函数的返回类型。
历史背景
libffi 最初由 Anthony Green(SO 用户:anthony-green)开发,灵感来自 Silicon Graphics 的 Gencall 库。 Gencall 由 Gianni Mariani 开发,然后被 SGI 雇用,目的是允许按地址调用函数并为特定调用约定创建调用框架。 Anthony Green 改进了这个想法并将其扩展到其他架构和调用约定以及开源 libffi。
用 libffi 调用 pow
#include <stdio.h>
#include <math.h>
#include <ffi.h>
int main()
{
ffi_cif call_interface;
ffi_type *ret_type;
ffi_type *arg_types[2];
/* pow signature */
ret_type = &ffi_type_double;
arg_types[0] = &ffi_type_double;
arg_types[1] = &ffi_type_double;
/* prepare pow function call interface */
if (ffi_prep_cif(&call_interface, FFI_DEFAULT_ABI, 2, ret_type, arg_types) == FFI_OK)
{
void *arg_values[2];
double x, y, z;
/* z stores the return */
z = 0;
/* arg_values elements point to actual arguments */
arg_values[0] = &x;
arg_values[1] = &y;
x = 2;
y = 3;
/* call pow */
ffi_call(&call_interface, FFI_FN(pow), &z, arg_values);
/* 2^3=8 */
printf("%.0f^%.0f=%.0f\n", x, y, z);
}
return 0;
}
我认为我可以断言 libffi 是一种可移植的方式来做我所要求的,这与 Antti Haapala 的断言相反,即没有这样的方式。如果我们不能将 libffi 称为可移植技术,考虑到它在编译器和架构之间的移植/实现程度,以及哪个接口符合 C 标准,我们也不能将 C 或任何东西称为可移植的。
信息和历史摘录自:
https://github.com/atgreen/libffi/blob/master/doc/libffi.info
http://en.wikipedia.org/wiki/Libffi