2016-10-10 9 views
1

JNA를 사용하여 내 프로그램에서 다른 .so를 호출 할 때 몇 가지 문제가 있습니다. 내 기본 공유 라이브러리에서 같은 이름의 메서드를 선언 할 수없는 것으로 보입니다.동일한 메소드 이름을 가진 많은 라이브러리를로드하는 JNA

예 :

#include <stdio.h> 
int anotherMethod() { 
    return 100; 
} 
int method() { 
    return 1 + anotherMethod(); 
} 

그리고 native2.c : 나는 native1.c이

#include <stdio.h> 
int anotherMethod() { 
    return 200; 
} 
int method() { 
    return 2 + anotherMethod(); 
} 

각이 공유 라이브러리에 컴파일 (libnative1.so 및 libnative2.so) .

$ gcc -m64 -shared -fPIC -o linux-x86-64/libnative1.so native1.c 
$ gcc -m64 -shared -fPIC -o linux-x86-64/libnative2.so native2.c 

(I은 64 비트 리눅스 오전)

그래서 호출 방법() 반환해야합니다 : native1

  • 202

    • 101 native2

    에서 나는 것 작은 자바 메인에서보십시오 :

    I 얻을
    public interface Native2 extends Library { 
        int method(); 
    } 
    

    public interface Native1 extends Library { 
        int method(); 
    } 
    

    그리고

    을 : 63,210
    public static void main(String[] args) { 
        Native1 native1 = (Native1) Native.loadLibrary("native1", Native1.class); 
        Native2 native2 = (Native2) Native.loadLibrary("native2", Native2.class); 
        System.out.println(native1.method()); 
        System.out.println(native2.method()); 
    } 
    

    라이브러리 인터페이스 미니멀있다

    101 //

    102 //이어야한다 OK 202!

    좋은 메소드()가 호출되었지만 내 원시 코드가 anotherMethod()를 호출하면 native1의 코드 만 호출됩니다.

    Native.loadLibrary()는 공유 라이브러리를로드하고 전개하여 첫 번째 "anotherMethod"심볼 만 존재하게합니다.

    내 실제 경우

    , C 코드 내 책임하에 아니라, 쉽게 각각을 구분하는 방법이 있나요 다른 편집기에 의해 제공됩니다, 그래서 덜 내가 가지고는 최고의

    입니다 편집 공유 라이브러리, 네임 스페이스 또는 gcc 옵션과 같이 내가 놓친 것?

  • +0

    C를 사용하여 똑같은 일을하면 효과가 있습니까? 다른 심볼 범위로 라이브러리를로드 할 수도 있습니다. 기본적으로'RTLD_GLOBAL'이로드됩니다.'RTLD_LOCAL' (dlopen의 man 페이지를보십시오)을 사용하면 더 좋은 결과를 얻을 수 있습니다. – technomage

    +0

    주 사용 dlopen을 사용하면 오류없이 메소드를 호출 할 수 있습니다 (101 및 202가 인쇄 됨). 그러나 RTLD_GLOBAL 옵션은 동일한 오류 (101 및 102)를 생성합니다. JNA에서 RTLD_LOCAL을 시뮬레이트하는 방법이 있다고 생각하십니까? – Lioda

    답변

    0

    Native.loadLibrary()을 호출 할 때 RTLD_LOCAL에 해당하는 값을 갖는 Library.OPTION_OPEN_FLAGS 키를 포함한 Map 옵션을 제공 할 수 있습니다. 그러면 문제가 해결 될 것입니다.

    Map options = new HashMap(); 
    int RTLD_LOCAL = 0x4; // or whatever value it has on your platform 
    options.put(Library.OPTION_OPEN_FLAGS, RTLD_LOCAL); 
    Mylib lib = Native.loadLibrary("mylib", Mylib.class, options); 
    

    당신은 대상 시스템에 grep RTLD_LOCAL /usr/include/*.hRTLD_LOCAL의 가치를 찾아 볼 수 있습니다.

    +0

    네, 좋은 옵션입니다. 고맙습니다. 내 시스템에서 나는 값 1 (RTLD_LAZY + RTLD_LOCAL)을 사용해야하고 그것은 좋은 것처럼 보인다. – Lioda