2010-02-11 7 views
7

C++ 라이브러리에 사용되는 JNA에 대한 온라인 참조 (stackoverflow 중 일부 포함)가 발견되었지만 JNA 문서에서 찾을 수있는 내용이 없습니다. 특히 C++ 클래스를 래핑하는 방법이없는 것 같습니다.Java Native Access는 C++을 사용하지 않습니다. 그렇습니까?

RTAudio를 사용하려면 기본 액세스가 필요하지만 RTAudio의 모든 기능은 RTAudio 클래스의 멤버 기능입니다. 그래서 확인하기 위해, JNA는 올바르게가는 길은 아니십니까?

답변

9

이 질문에 대한 대답은 how to call C++ instance methods using JNA이며, 가능하지만 어떤 작업을해야 할 것입니다. 특히 실제로 호출해야하는 함수가있는 extern "C" 래퍼를 작성해야합니다.

임의의 type* function() 정의의 경우 JNA를 사용하여 com.sun.jna.Pointer을 반환하는 방법을 매핑 할 수 있지만 JNA의 C++ 객체에 대해 메소드를 호출 할 수는 없습니다.

이 간단한 해결 방법은 개체의 메서드를 호출하는 C 인터페이스 라이브러리를 작성하는 것입니다 ... 일부 멤버 함수 foo()이있는 경우 C++ 코드에서 C 메서드를 내보낼 수 있습니다.

extern "C" void bar(type* var){ 
    var->foo(); 
} 

분명히 이것은 당신을 위해 몇 가지 작업을 추가 할 것입니다 ... 그러나 나는 JNI으로 전환하는 오버 헤드가 거의 같을 것이라고 생각합니다.

JNA는 방법은 DLL에 수출되는 방식에 대한 관심 - 그것은 (그러므로 extern "C") C++ 장식없이 을해야합니다, 그래서 당신은 당신이 노출하지 않고 그러한 방법에서 필요 무엇이든 할 수 있습니다 당신이 부르는 방법.

위의 내 인위적인 예제에서 이것은 DLL 내에 정의되어있는 한 사실상 노출 될 필요가없는 한 foo()을 의미합니다. C++ 함수이기 때문에 JNA는 직접 호출 할 수는 없지만 JNA에서 호출 할 수있는 함수 내에서 호출 할 수 있습니다. 따라서 제안 된 솔루션이 작동합니다.

그렇습니다. 예, 단일 함수로 모든 멤버 함수 (작성, 작동, 삭제)에 대한 호출을 완전히 캡슐화 할 수 있으며 JNA는 상관하지 않습니다.

+0

멋진 답변 감사합니다.일반 C 메소드가 함수 본문 내에 C++ 클래스 인스턴스를 만들고 멤버 함수를 호출 한 다음 객체를 삭제하는 경우이 멤버 함수 바인딩을 직접 피할 수 있습니까? 아니면 JNA가 어떻게 든 "알"수 있고, C 함수 인 것처럼 보이지만 몸속에 C++을 사용하는 것을 거부 할 것인가? –

+1

@carneades - 댓글이 허용하는 것보다 많은 공간이 필요합니다. 게시물의 편집을 참조하십시오. –

+0

감사합니다. Mark, 이것이 완벽하게 작동했습니다! extern "C"void rtattempt (void) { RtAudio :: RtAudio 오디오; std :: cout << "num devices :"<< audio.getDeviceCount() << std :: endl; } –

2

시도 Swig. 그것은 당신을위한 C++ 클래스를위한 래퍼를 만들 것입니다.

2

BridJ은 제한된 C++ 지원 (+ 전체 지원 JNAerator)을 추가 한 JNA의 영적인 하위 항목입니다. 너무 많은 템플릿을 사용하지 않는 경우 그냥 ...

(면책 조항 : 나는 BridJ & JNAerator의 저자 해요) 작동 할 수