2012-12-02 5 views
1

나 C++로 작성된 의미 또는 CVM에서 원시 함수를 호출하는 방법은 무엇입니까? 기본으로

난에, 프로그래밍 언어 기반으로 자바를 만들고있어 그것이 VM 바이트 코드 컴파일러 언어를 가지고있다. 그래서 언어의 기능, 같은 for 루프, 변수, 산술 및 구현

는 나에게 문제가되지 않습니다; 그러나 Java와 같은 기본 기능을 실행할 수 있습니다.

나는 나의 언어로 작성된 프로그램은 하드웨어와 OS와 윈도우, 인터페이스를 생성하는 것이 가능하게하기 위해 기본 기능을해야하고, 단순한 수학 아니다 무엇이든 할.

나는 JNI에 대해 들어 봤는데, 분명히 내가 좋아할만한 것으로 보이지만, 그런 식으로 구현하는 방법을 모르겠습니다. 내 VM으로

는 C++로 구현, 내가 컴파일 시간에 그것을 내 기본 기능 #include HPP 파일이있을 수 있으며, 다음 동적 dll 년대 또는 so 's을 (를)로드 할 수 있다는 것을 알고 있지만,이'아무튼 다른 원시 기능을 실행할 수 있기를 원할 때마다 VM을 다시 컴파일해야하기 때문에 실제로는 좋은 솔루션처럼 보입니다.

문제는 다음과 같습니다. C++ 프로그램 (VM)은 동적으로 (런타임에서 바이트 코드의 지시에 따라)보다 정확하게 C++ 함수로 라이브러리를로드 한 다음 해당 함수를 실행하지 않고 그 함수를 실행할 수 있습니까? 일부 헤더 파일에서 미리 선언 되었습니까?

+1

원하는 코드 샘플을 제공해 주시겠습니까? –

+0

Windows에서 LoadLibrary() 및 GetProcAddress()를 사용합니다. Linux는 다른 이름과 동일한 기능을합니다. 이것들은 인자와 반환 값의 수와 타입을 숫자로 알기는 어렵습니다. –

+0

@BhavikAmbani 물론, 몇 시간 후에 집에가 자마자. – corazza

답변

1

libffi을보세요. 함수 주소와 호출 서명이 주어진 모든 함수를 호출하는 메소드를 제공합니다.

서명이 무엇인지 알아내는 방법은 컨텍스트에 따라 다릅니다. 인수 유형에 따라 광범위한 호출을 유추 할 수 있습니다. JNA은 명시 적 Java 인터페이스, 메소드 선언 또는 동적 호출 인수에서 원시 호출 시그니처를 유추합니다.

생성자, 메모리 관리 및 개체 메서드 디스패치를 ​​처리하는 간단한 함수 호출을 넘어서는 것은 더 복잡하지만 여전히 동일한 기본 원칙을 기반으로합니다. 내가 언급 보지

+0

이것은 분명히 필요한 것 같습니다. 그러나 일부 동적으로로드 된 공유 객체 ('dlopen()')에서 함수에 대한 포인터를 얻는 방법을 정확히 모르겠습니다. 인수의 이름, 인수의 유형, 함수의 리턴 유형을 알고 있습니다. 왜냐하면 그것이 제 언어로 설명 되었기 때문에 포인터를 원시 함수로 가져 오는 방법을 모르겠습니다. 네이티브 함수가'X'라고 불리는 것을 알고 있다면 포인터를 얻을 수 있습니까? – corazza

+0

'dlsym()'은 이름을 가진 심볼을 찾는다. 일반적으로 내 보낸 기호는 호출 할 수있는 함수이거나 데이터 액세스를 위해 전역 변수의 주소입니다. – technomage

+0

이제'dlopen()'과'dlsym()'을 얻었습니다. LibFFI의 실제 필요성은 어디에 있습니까? – corazza

0

하나 개의 주제는 새로운 VM 기능은 C++ 스택 호출 언어, 방법 VM에 다시 C++ 함수에서 반환 값을 전달하는 방법에서 인수를 전달하는 방법이다.

새 언어로 pow (3) 함수를 사용 가능하게 만들려고합니다. 말씀 드리지만, 펑() 서명이

double pow (double base, double power) 

가장 간단한 방법은이

void 
language::pow(VM * pVM) 
{ 
    double arg2 = pVM->PopDouble(); 
    double arg1 = pVM->PopDouble(); 
    double result = pow(arg1, arg2); 
    pVM->PushDouble(result); 
} 

같은 것입니다하지만 당신이 후에 무엇을 같은 소리하지 않습니다. dlopen을 통합() & dlsym을()

void 
language::pow(VM * pVM) 
{ 
    double arg2 = pVM->PopDouble(); 
    double arg1 = pVM->PopDouble(); 
    void *handle = dlopen("libm", RTLD_LAZY); 
    if (!handle) { /*...return; ...*/ } 
    typedef double (* pfPow) (double, double); 
    pfPow pPow = (pfPow) dlsym(handle, "pow"); 
    if (!pPow) { /*...return; ...*/ } 
    double result = (* pPow)(arg1, arg2); 
    pVM->PushDouble(result); 
} 

처럼 뭔가를 얻을 수 그러나 그것은 더 악화입니다. 언어에 액세스 할 수있게하려는 C++ 함수마다 스텁 함수가 필요합니다.그것은 당신 같은 소리

언어 내가 ++ C에서 그것을 구현하는 방법을 모르는

double result = eval_double("libm", "pow", arg1, arg2); 

같은 것을 갖고 싶어. Varags는 모든 유형의 C++ 인수를 가져 오는 것을 지원합니다. 그러나 임의의 유형의 C++ 인수를 푸시하는 API는 없습니다.

관련 문제