2013-04-27 5 views
0

위에서 달성 할 수 있는지 알고 싶습니다. 리눅스에서는 dlopen, dlsym 메소드를 사용하여 라이브러리를로드하고 메소드를 호출 할 수 있습니다. 그러나 호출하기 전에 void * 포인터를 해당 유형으로 캐스트하려면 함수 프로토 타입을 알아야합니다.프로토 타입을 모른 채 런타임에 C 함수를 동적으로 호출

가정 프로토 메타

이를 달성하는 방법이 있는가 (일부 디스크립터 파일 등을 이용하여) 외부 적으로 제공 될 수 있는가?

+0

이것은 일반적으로 불가능합니다. (varargs를 사용하는 해킹이 가능할 수도 있지만) 믿습니다. 특별한 목적이 있습니까? –

+0

C는 python이나 javascritp와 같은 동적 언어가 아닙니다. 함수의 프로토 타입을 알아야합니다. –

+0

@larsmans 사실 이것은 RPC 서버에 대해 작성하려고하는 일부 실험 코드 용입니다. HTTP 호출은 런타임에로드 할 수있는 라이브러리에있는 일부 함수를 호출하는 데 사용됩니다. – chamibuddhika

답변

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

+1

@chamibuddhika 그것은 무겁고 사악한 어셈블리 해킹을 사용합니다 :) –

관련 문제