2013-04-27 15 views
0

我想知道是否有可能實現上述目標。顯然,可以在Linux中使用dlopen, dlsym方法加載庫並調用它的方法。但它需要知道函數原型,以便在調用之前將指針指向相應類型的void *在運行時動態調用C函數而不知道它的原型

假定原型元數據(使用一些描述符文件等)

有一種方法來完成此可以外部提供?

+0

這是不可能的一般,我相信(儘管也許一些使用可變參數的黑客可能工作)。你有一個特定的目的? – 2013-04-27 14:36:46

+0

C不是像Python或javascritp這樣的動態語言,你必須知道你的函數的原型 – 2013-04-27 14:47:31

+0

@larsmans事實上,這是爲了一些實驗性代碼,我試圖爲RPC服務器編寫一個類似功能的代碼,其中參數是通過HTTP調用將用於調用可以在運行時加載的庫中的一些函數。 – chamibuddhika 2013-04-27 16:45:04

回答

4

這是可以肯定的,但不要期待任何便攜。例如,您可以使用臭名昭着的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); 

像這樣的東西應該讓你開始。

+0

這似乎是可行的。接受這是正確的答案,因爲我沒有看到這種方法的任何絆腳石。會試試看看。但只是好奇這個圖書館如何實現一些不受它自己語言支持的東西。 – chamibuddhika 2013-04-27 17:08:25

+1

@chamibuddhika它使用重罪和邪惡組合黑客:) – 2013-04-27 17:24:09

相關問題