2009-04-09 2 views
2

다른 프로세스가 (유닉스 소켓을 통해) 함수를 호출 할 수있게하려는이 프로그램이 있습니다. 메시지 프로토콜은 매우 간단하며, 함수 이름, 함수 서명 및 매개 변수를 보유하는 버퍼 (char *)입니다.C 스텁이없는 RPC

내 프로그램의 모듈이 기능에 액세스 할 수있게하려는 경우 이름과 서명을 라이브러리에 등록합니다. 내가 직면하고있는 문제는 요청이 들어 오면 물리적으로 함수를 호출하는 것입니다. RPC와 Java RMI와 같은 라이브러리를 살펴 보았지만 호출을 감싸는 스텁을 생성해야합니다. 제가 작업하고있는 시스템은 매우 역동적이며, 수정할 수없는 다른 사람들의 코드와도 인터페이스해야합니다. 요청이 들어 오면, 나는 몇 가지 오류 검사를 할

//   func ptr name  signature 
REG_FUNCTION(somefunc, "somefunc", "i:id"); 

는, 한 번 유효 내가 원하는 : 나는 도서관에 등록 지금

int somefunc(int someparam, double another) 
{ 
    return 1234; 
} 

: 같은

그러니까 기본적으로, 함수 보일 수 있습니다 함수를 호출합니다. 그래서 변수가 있습니다

void * funcptr = (the requested function); 
char * sig = (the function signature); 
char * params = (a buffer of function parameters); 
//note that the params buffer can hold data types of arbitrary lengths 

가 어떻게 C에서 매개 변수를 사용하여 함수를 호출 할 수 있습니다 ?

감사합니다.

+0

서명은 무엇이 필요합니까? 클라이언트가 함수를 호출하거나 somefunc를 포함하는 라이브러리에 요청을 전달합니까? 어떤 설명이 도움이 될 것입니다! – dirkgently

답변

2

일반적으로 C 만 사용하여이 문제를 완전히 해결할 수 있다고 생각하지 않습니다. 예를 들어 대상 함수에서 사용하는 호출 규칙을 알 수 없습니다. 컴파일러가 "부정 행위"를하거나 적어도 추측 할 필요가있는 위험이 있습니다. 컴파일러가 레지스터에 전달 된 인수를 사용하여 등록 된 함수를 작성하기로 결정한 경우 (아마도 일부 최적화 설정 (또는 다른 컴파일러로 작성된 경우))?

일반적으로 C에서 주어진 인수 세트를 사용하여 함수를 호출하고 임의의 바이트 버퍼에서 인수의 값을 언 패킹해야한다고 표현할 방법이 없습니다.

이 같은 뭔가 끔찍한 할 수 :

enum { VOID_INT, VOID_INT_DOUBLE, VOID_DOUBLE_INT, ... } Signature; 

void do_call(const void *userfunction, const void *args, Signature sig) 
{ 
    switch(signature) 
    { 
    case VOID_INT: 
    { 
     int x = *(int *) args; 
     void (*f)(int) = userfunction; 
     f(x); 
     break; 
    } 
    case VOID_INT_DOUBLE: 
    ... 
    } 
} 

을하지만이 확장 성 같은 대륙에 거주하지 않는 것을 아주 분명하다. 물론 합리적인 세트의 리턴 유형 및 인수 유형에 대해이 코드를 자동 생성 할 수 있습니다. 감기에 void *에 /에서 함수 포인터를 캐스팅 할 때 여전히 약간의 차이가있을 수 있지만 그럴 수도 있습니다. 그래도 미리 생성 된 코드가없는 서명을 사용자에게 넘겨 줄 위험이 있습니다.

0

체크 아웃 libffi 이 라이브러리는 런타임에 지정된 매개 변수 집합을 사용하여 함수를 호출 할 수있게합니다.