문제

JNA는 JNI와 비교하여 기본 코드를 호출하는 데 사용하기가 약간 쉬운 것 같습니다. JNA에서 JNI를 어떤 경우에 사용 하시겠습니까?

도움이 되었습니까?

해결책

  1. JNA는 C ++ 클래스의 매핑을 지원하지 않으므로 C ++ 라이브러리를 사용하는 경우 JNI 래퍼가 필요합니다.
  2. 많은 메모리 복사가 필요한 경우. 예를 들어, 큰 바이트 버퍼를 반환하는 하나의 메소드를 호출하고 무언가를 변경 한 다음이 바이트 버퍼를 사용하는 다른 방법을 호출해야합니다. 이 버퍼를 C에서 Java로 복사 한 다음 Java에서 C로 다시 복사해야합니다. 이 경우 JNI는 복사 없이이 버퍼를 C로 유지하고 수정할 수 있기 때문에 성능에서 승리합니다.

이것들은 내가 직면 한 문제입니다. 어쩌면 더있을 수도 있습니다. 그러나 일반적으로 성능은 JNA와 JNI간에 다르지 않으므로 JNA를 사용할 수있는 곳마다 사용하십시오.

편집하다

이 대답은 매우 인기있는 것 같습니다. 그래서 다음은 다음과 같습니다.

  1. C ++ 또는 COM을 맵핑 해야하는 경우 Jnaerator의 제작자 인 Oliver Chafic의 라이브러리가 있습니다. 브리드. 여전히 젊은 도서관이지만 많은 흥미로운 기능이 있습니다.
    • Dynamic C / C ++ / COM Interop : C ++ 메소드를 호출하고 C ++ 객체를 작성하고 (Java의 서브 클래스 C ++ 클래스!)
    • 제네릭을 잘 사용하는 간단한 유형 매핑 (포인터를위한 훨씬 더 좋은 모델 포함)
    • 완전한 jnaerator 지원
    • Windows, Linux, MacOS X, Solaris, Android에서 작업
  2. 메모리 복사와 관련하여 JNA는 직접 바이 테 버퍼를 지원하므로 메모리 복사를 피할 수 있습니다.

따라서 가능한 한 JNA 또는 Bridj를 사용하는 것이 더 낫고 성능이 중요한 경우 JNI로 되돌리는 것이 더 낫다고 생각합니다. 기본 기능을 자주 호출 해야하는 경우 성능 히트가 눈에 띄기 때문입니다.

다른 팁

그런 일반적인 질문에 대답하기는 어렵습니다. 가장 분명한 차이점은 JNI를 사용하면 유형 변환이 Java/Native 테두리의 기본 측면에서 구현되고 JNA의 경우 유형 변환이 Java에서 구현된다는 것입니다. 이미 C의 프로그래밍에 대해 매우 편안하다고 느끼고 일부 기본 코드를 직접 구현해야한다면 JNI가 너무 복잡해 보이지 않는다고 가정합니다. Java 프로그래머이고 제 3 자 기본 라이브러리 만 호출 해야하는 경우 JNA를 사용하는 것이 아마도 JNI의 명백한 문제를 피하는 가장 쉬운 경로 일 것입니다.

나는 차이를 벤치마킹 한 적이 없지만, 디자인 때문에, 적어도 일부 상황에서 JNA와의 유형 변환이 JNI보다 더 나빠질 것이라고 가정합니다. 예를 들어 배열을 통과 할 때 JNA는 각 기능 호출 시작시 Java에서 Native로, 기능 호출의 끝에서 다시 변환합니다. JNI를 사용하면 배열의 기본 "보기"가 생성 될 때 자신을 제어 할 수 있습니다. 배열의 일부만을 생성하고, 여러 기능 호출에 대한보기를 유지하고 마지막에보기를 릴리스하고 원하는지 결정하십시오. 변경 사항을 유지 (잠재적으로 데이터를 복사해야 함) 또는 변경 사항 (사본이 필요하지 않음)을 폐기합니다. 메모리 클래스를 사용하여 JNA와 함께 함수 호출을 통해 기본 배열을 사용할 수 있지만 메모리 복사가 필요합니다. 이는 JNI와 관련이있을 수 있습니다. 그 차이는 관련이 없을 수도 있지만 원래 목표는 기본 코드로 일부를 구현하여 응용 프로그램 성능을 높이는 것이라면 더 나쁜 성능 브리지 기술을 사용하는 것이 가장 분명한 선택이 아닌 것 같습니다.

  1. JNA가 있기 전에 몇 년 전에 코드를 작성하거나 1.4 사전 JRE를 목표로 삼고 있습니다.
  2. 함께 작업하는 코드는 DLL 에 없습니다.
  3. LGPL과 호환되지 않는 코드를 작업 중입니다.

그것은 내가 내 머리 꼭대기에서 나올 수있는 것입니다. 또한 그들이 제공하는 것보다 더 나은 인터페이스를 원한다면 JNA를 피할 수 있지만 Java에서 코딩 할 수 있습니다.

그건 그렇고, 우리 프로젝트 중 하나에서, 우리는 매우 작은 JNI 풋 프린트를 보관했습니다. 우리는 도메인 객체를 나타 내기 위해 프로토콜 버퍼를 사용했으며, 따라서 Java와 C를 브리지 할 기본 기능이 하나뿐입니다 (물론 C 함수는 다른 많은 함수를 부릅니다).

직접적인 답이 아니며 JNA에 대한 경험이 없지만, 내가 볼 때 JNA를 사용한 프로젝트 그리고 svnkit, Intellij Idea, Netbeans IDE 등과 같은 이름을 보면, 나는 그것이 꽤 괜찮은 도서관이라고 믿는 경향이 있습니다.

사실, 나는 JNI 대신 JNI 대신 JNA를 사용했을 때 JNI (지루한 개발 프로세스가있는)보다 간단 해 보이기 때문에 JNA를 사용했을 것이라고 생각합니다. 너무 나쁘다. JNA는 현재 출시되지 않았다.

JNI 성능을 원하지만 복잡성에 어려움을 겪고 있다면 JNI 바인딩을 자동으로 생성하는 도구를 사용하는 것을 고려할 수 있습니다. 예를 들어, 자넷 (면책 조항 : 내가 썼다)는 단일 소스 파일에서 Java와 C ++ 코드를 혼합 할 수 있으며, 예 : 표준 Java 구문을 사용하여 C ++에서 Java로 호출 할 수 있습니다. 예를 들어, C 문자열을 Java 표준 출력에 인쇄하는 방법은 다음과 같습니다.

native "C++" void printHello() {
    const char* helloWorld = "Hello, World!";
    `System.out.println(#$(helloWorld));`
}

그런 다음 Janet은 백틱으로 처리 된 Java를 적절한 JNI 호출로 변환합니다.

나는 실제로 JNI와 JNA와 함께 간단한 벤치 마크를했다.

다른 사람들이 이미 지적했듯이 JNA는 편의를위한 것입니다. JNA를 사용할 때는 기본 코드를 컴파일하거나 쓸 필요가 없습니다. JNA의 기본 라이브러리 로더는 또한 내가 본 것 중 가장 좋은/가장 쉬운 중 하나입니다. 슬프게도, 당신은 JNI에 그것을 사용할 수 없습니다. (그래서 내가 쓴 이유입니다 System.LoadLibrary ()의 대안 이는 JNA의 경로 규칙을 사용하고 클래스 경로 (즉, 항아리)의 원활한 하중을 지원합니다.)

그러나 JNA의 성능은 JNI의 성능보다 훨씬 나빠질 수 있습니다. 간단한 기본 정수 증분 함수 "Return Arg + 1;"라고하는 매우 간단한 테스트를했습니다. JMH로 수행 된 벤치 마크는 해당 기능에 대한 JNI 호출이 JNA보다 15 배 빠른 것으로 나타났습니다.

기본 함수가 4 값의 정수 배열을 요약하는보다 "복잡한"예는 여전히 JNI 성능이 JNA보다 3 배 빠르다는 것을 보여주었습니다. 감소 된 이점은 아마도 JNI의 배열에 액세스하는 방법 때문일 것입니다. 제 예제는 일부 요약 작업 중에 일부를 만들어 다시 출시했습니다.

코드 및 테스트 결과를 찾을 수 있습니다 Github에서.

우리는 프로젝트에서 DLL을 호출하기 위해 그들 중 하나를 결정해야했고 실시간 제약 조건이 있었기 때문에 성능 비교를 위해 JNI와 JNA를 조사했습니다. 결과는 JNI가 JNA보다 더 큰 성능을 가지고 있음을 보여 주었다 (약 40 회). 아마도 JNA에서 더 나은 성능을위한 트릭이있을 수 있지만 간단한 예는 매우 느립니다.

내가 뭔가를 놓치지 않는 한, JNA와 JNI의 주요 차이점은 JNA를 사용하여 Native (c) 코드에서 Java 코드를 호출 할 수 없습니까?

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top