我想知道是否有可能实现上述目标。显然,可以在Linux中使用dlopen, dlsym
方法加载库并调用它的方法。但它需要知道函数原型,以便在调用之前将指针指向相应类型的void *
。在运行时动态调用C函数而不知道它的原型
假定原型元数据(使用一些描述符文件等)
有一种方法来完成此可以外部提供?
我想知道是否有可能实现上述目标。显然,可以在Linux中使用dlopen, dlsym
方法加载库并调用它的方法。但它需要知道函数原型,以便在调用之前将指针指向相应类型的void *
。在运行时动态调用C函数而不知道它的原型
假定原型元数据(使用一些描述符文件等)
有一种方法来完成此可以外部提供?
这是可以肯定的,但不要期待任何便携。例如,您可以使用臭名昭着的libffi库。伪C中的虚拟示例:
// We make some kind of descriptor structure and possible return and argument types
enum c_type {
C_TYPE_CHAR,
C_TYPE_INT,
C_TYPE_FLOAT,
C_TYPE_PTR,
C_TYPE_VOID
};
struct func_proto_desc {
enum c_type ret_type;
int n_args; // Reasonable convention: -1 for variadic
c_type *arg_types;
};
// Imaginary function that parses textual metadata and returns a function descriptor
void parse_func_desc(const char *str, struct func_proto_desc *desc);
// this is how to use it:
struct func_proto_desc fproto;
parse_func_desc("void (*)(int, float, const char *)", &fproto);
ffi_cif cif;
ffi_type *args[3];
void *vals[3];
int n = 42;
float f = 3.1415927;
const char *s = "Hello world!";
vals[0] = &n;
vals[1] = &f;
vals[2] = &s;
// Here you can set up the types according to the type description
// that the parser function returned
// (this one is an imaginary function too)
populate_ffi_types_from_desc(args, &fproto);
// Use libffi to call the function
ffi_prep_cif(&cif, FFI_DEFAULT_ABI, fproto->n_args, &ffi_type_void, args);
ffi_call(&cif, func_ptr, NULL, vals);
像这样的东西应该让你开始。
这似乎是可行的。接受这是正确的答案,因为我没有看到这种方法的任何绊脚石。会试试看看。但只是好奇这个图书馆如何实现一些不受它自己语言支持的东西。 – chamibuddhika 2013-04-27 17:08:25
@chamibuddhika它使用重罪和邪恶组合黑客:) – 2013-04-27 17:24:09
这是不可能的一般,我相信(尽管也许一些使用可变参数的黑客可能工作)。你有一个特定的目的? – 2013-04-27 14:36:46
C不是像Python或javascritp这样的动态语言,你必须知道你的函数的原型 – 2013-04-27 14:47:31
@larsmans事实上,这是为了一些实验性代码,我试图为RPC服务器编写一个类似功能的代码,其中参数是通过HTTP调用将用于调用可以在运行时加载的库中的一些函数。 – chamibuddhika 2013-04-27 16:45:04