2010-07-07 5 views
3

일종의 런타임 시스템/인터프리터를 작성하는 중입니다.해야 할 일 중 하나는 외부에있는 c/C++ 함수를 호출하는 것입니다. 라이브러리.C/C++ 프로토 타입이 알려지지 않은 함수의 동적로드

리눅스에서 dlfcn.h 함수를 사용하여 라이브러리를 열고 그 안에있는 함수를 호출합니다. 문제는, dlsysm()을 사용할 때 반환되는 함수 포인터가 함수 인수와 반환 유형을 알 수 있도록 호출되기 전에 적절한 유형으로 변환되어야한다는 것입니다. 그러나 라이브러리에서 임의의 함수를 호출하는 경우 분명히 알 수 있습니다. 컴파일시이 프로토 타입을 모른다.

그래서 내가 묻는 것은 동적으로로드 된 함수를 호출하고 인수를 전달하고 리턴 값을 검색하는 방법이 있습니까 프로토 타입을 알지 않고 있습니까?

은 지금까지 나는이 작업을 수행하는 쉬운 방법이없는 결론에 도달했지만, 내가 찾은 몇 가지 해결 방법은 다음과 같습니다

  • 내가 같은를로드 할 모든 기능을 확인하십시오 프로토 타입을 만들고 매개 변수와 반환 값을 검색하기 위해 이러한 함수에 대한 정렬 메커니즘을 제공합니다. 이것은 내가 현재하고있는 일이다.

  • 인라인 asm을 사용하여 매개 변수를 스택에 푸시하고 반환 값을 읽습니다. 가능하다면이 일을 분명히하고 싶습니다!

누구나 아이디어가 있다면 크게 환영 할 것입니다.

편집 :

지금 정확히 발견 내가 찾던 : 나는 인정한다하더라도 (

http://sourceware.org/libffi/

"휴대용 외부 함수 인터페이스 라이브러리"

나는 원래 질문에서 더 명확하게 할 수 있었다!)

+0

컴파일 타임에 함수 프로토 타입을 알 수 없다는 주장을 이해하지 못합니다. 제 말은 dlsym()을 호출하고 그 결과로 무엇을할까요? '인수'는 정확히 어디에서 얻고 있습니까? 인수의 존재는 나에게 당신이 함수 프로토 타입에 대한 아이디어를 가지고 있다는 것을 의미합니다. –

+0

매개 변수 또는 반환 형식을 모르는 경우 어떻게 함수를 호출합니까? – Stephen

+0

이 함수는 자바 JNI와 마찬가지로 다른 언어의 소스 코드에 지정됩니다. 따라서 dlysm을 호출하는 함수의 이름을 쉽게 얻을 수 있지만 인수와 유형은로드 된 함수에 전달할 수없는 다양한 AST 노드로 표시됩니다. –

답변

1

나는 루비 FFI 라이브러리가 당신이 요구하는 것을 성취한다고 믿는다. 그것은

http://wiki.github.com/ffi/ffi/

당신은 아마 당신의 스크립트 언어에서 직접 사용할 수 없습니다. 특별히 그들을 연결하지 않고 외부 동적 링크 라이브러리 함수 를 호출하지만 아이디어 이식 perhapps 수 있습니다.

- 브래드 펠란 http://xtargets.heroku.com

2

디스패치 기능을 외부 라이브러리에 추가합니다 (예 : 하나는 함수 이름과 일종의 변형 유형의 N (선택적) 매개 변수를 취하여 변형을 반환하는 것입니다. 그런 식으로 디스패치 함수 프로토 타입을 알 수 있습니다. 그러면 dispatch 함수는 함수 이름에 대한 조회 (또는 스위치)를 수행하고 해당 함수를 호출합니다.

많은 기능이 있으면 분명히 유지 관리 문제가됩니다.

6

C/C++에서 함수 리플렉션 (즉 런타임에 해당 유형에 대한 정보 가져 오기)을 지원하는지 묻는 것입니다. 슬프게도 대답은 '아니오'입니다.

표준 계약 (당신이 말한 것처럼)을 준수해야하거나, 인수를 모른 채 런타임에 함수를 호출하려고하는 메커니즘을 구현해야합니다.

함수에 대한 지식이 없으므로이 함수를 호출 할 수 없기 때문에 인터프리터/"런타임 시스템"에 적어도 사용자 입력이 있거나 비슷한 함수를 호출하려고한다는 것을 추측 할 수 있다고 가정합니다 그 논쟁을 완전히 무의미하지 않은 무언가를 되 찾는 것과 같습니다.그 룩업은 반성과 적절한 런타임 유형의 시스템이 작동하더라도 그 자체로 구현하기가 어렵습니다. 호출 규칙, 링키지 스타일 및 플랫폼을 섞어 놓으면 곧 비참 해집니다.

계획에 충실하고 동적으로로드하는 함수에 대해 잘 정의 된 계약을 시행하고 그에 따라 잘만 만들어야합니다.

0

내가 런타임 시스템/통역의 종류를 작성하는 과정에있어, 나는 할 수 있어야 것들 중 하나가 호출 C/C++로 함수는 외부 라이브러리에 있습니다.

아마도 TclPython이 어떻게 수행하는지 예제를 확인할 수 있습니다. Perl에 익숙하다면 Perl XS을 확인할 수도 있습니다.

일반적으로 인터프리터와 대상 C 라이브러리 사이에 별도의 게이트웨이 라이브러리가 있어야합니다. Perl XS에 대한 나의 경험에서 비롯된 주요 원인은 메모리 관리/가비지 콜렉션과 인터프리터의 언어에 직접 매핑하기가 어렵거나 불가능한 C 데이터 유형입니다.

그래서 내가 묻는 것은 동적으로로드 된 함수를 호출하고 인수를 전달하고 프로토 타입을 모른 채 반환 값을 검색하는 방법이 있습니까?

저에게 알려지지 않은 경우.

로드하려는 모든 함수의 프로토 타입이 동일하고 매개 변수와 반환 값을 검색하기위한 정렬 메커니즘을 제공해야합니다. 이것은 내가 현재하고있는 일이다.

이것은 내 프로젝트에서 다른 팀이하는 일입니다. 종종 RDBMS를 사용하여 플러그인에 대한

typedef std::list<std::string> string_list_t; 
string_list_t func1(string_list_t stdin, string_list_t &stderr); 

일반적인 작업 입력의 변환 또는 매핑 또는 확장을 수행하는 것입니다 : 그들은 그런 일에 외부 플러그인에 대한 표준화 된 API가 있습니다.

인터페이스의 이전 버전은 유지 관리가 어려워 고객, 제품 개발자 및 타사 플러그인 개발자에게 문제를 일으켰습니다. 플러그 - 인이 상대적으로 거의 호출되지 않는다는 사실에 의해 std :: string의 사소한 사용이 허용됩니다 (그리고 여전히 오버 헤드는 장소 전체에서 사용되는 SQL에 비해 땅콩입니다). 인수 stdin은 플러그인 유형에 따라 입력으로 채워집니다. 출력 매개 변수 stderr 내부에 'E :'로 시작하는 문자열이 있으면 경고로 간주되는 플러그인 호출이 실패했습니다 ('W :'는 경고 용이며 나머지는 자동으로 무시되므로 플러그인 개발/디버깅에 사용할 수 있음).

dlsym은 함수 테이블 (함수 public name, type, pointer 등)이있는 공유 라이브러리 배열에서 가져 오기 위해 미리 정의 된 이름을 가진 함수에서 한 번만 사용됩니다.

+0

감사합니다. 당신은 올바른 방향으로 나를 지적했습니다 :) –

0

내 솔루션 당신이 균일 한 프로토 타입에 동적 기능을 변환하는 generic proxy function을 정의 할 수있다, 이런 식으로 뭔가 :

사용자 정의 파일에서
#include <string> 
#include <functional> 

using result = std::function<std::string(std::string)>; 

template <class F> 
result proxy(F func) { 
    // some type-traits technologies based on func type 
} 

, 당신은 변환을 수행하는 정의에 추가해야합니다 : 런타임 시스템/통역에서

double foo(double a) { /*...*/ } 
auto local_foo = proxy(foo); 

, 당신은 foo-function을 정의 할 dlsym를 사용할 수 있습니다. 계산을 수행하는 것은 사용자 정의 함수 foo의 책임입니다.

관련 문제