2009-09-16 5 views
12

JNI 인터페이스를 통해 C++ 라이브러리를 사용하는 Java 응용 프로그램을 작성하고 있습니다. C++ 라이브러리는 Foo 유형의 객체를 생성합니다.이 객체는 JNI를 통해 Java에 정식으로 전달됩니다. JNI 인터페이스를 통한 출력 스트림 공유

는 라이브러리가 출력 기능

void Foo::print(std::ostream &os) 

을 가지고 있다고 가정하고 나는 자바 OutputStream out 있습니다. Java에서 Foo::print을 호출하여 출력을 out에 표시하려면 어떻게합니까? OutputStream을 JNI 계층의 std::ostream으로 강제 변환 할 수 있습니까? JNI 레이어의 버퍼에 출력을 캡처 한 다음 out에 복사 할 수 있습니까?

답변

0

에서 Foo :: print를 호출하여 출력이 밖으로 나올 수 있도록하려면 어떻게해야합니까?

개념적으로 말하기, 기존 자바의 OutputStream 인스턴스에 쓸 푸 :: 인쇄 (...)를 얻을 수있는 방법은 실제로 출력을 수행하는 자바로 콜백을 수행하는 C++ 표준 : : ostream에 구현을 작성하는 것입니다 .

그럴 수도 있지만 코드를 작성/유지 관리하고 싶지는 않습니다. 런타임에는 Java -> C++ -> Java에서 호출 할 것이므로 무작위로 JVM을 크래시 할 실수를 범할 수있는 많은 기회가 있습니다.

성병에 의 OutputStream을 강요 할 수있는 방법이 있습니까 :: JNI 층에서 ostream에?

AFAIK no.

나는 버퍼 JNI의 층에서 출력을 캡처 한 후 밖으로에 복사 할 수 있습니까?

대략적으로 이와 비슷한 것이 있습니까?

MyJNIThing m = ... 
    int myOstream = m.createMemoryBackedOStream(...); // native method 
    ... 
    m.someMethodWrapper(... myOStream); // native method 
    ... 
    byte[] data = m.getCapturedData(myOStream); // native method 
    out.write(data); 

바람을 피우며 좋은 하루를 보내십시오.

하지만 JNI에서 점차 복잡 해지는 것을 시도하기보다는 C++ 코드를 제거하는 것이 정말로 목표가되어야한다고 생각합니다. IMO, JNI는 최후의 수단으로 만 사용해야하며 Java에서 코드를 다시 작성하는 것을 피하기 위해 짧은 시간 내에 사용하지 않아야합니다.

+0

Java에서 라이브러리를 다시 구현하는 것은 옵션이 아닙니다 (크기가 크고 성숙하며 성능 집약적입니다). –

+0

아마도 Java에서 호출하려고해서는 안됩니다. 내 요점은 자신과 코드를 유지해야하는 사람들에게 많은 고통을 줄 가능성이 높다는 것입니다. –

+2

나는 JNI 코드가 그것이 공정하지 않다는 것을 철저히 피하여야한다고 말하는 것은 까다 롭다는 것에 동의한다. JNI를위한 장소가 분명히 있습니다. 특히 언급 된 op와 같은 대규모 레거시 프로젝트 및 작업을 완료하는 데 사용해야하는 제 3 자 API가 있습니다. 이것은 매우 유효한 질문입니다. 제가 답을 찾고 있습니다. – Cliff

1

writeup on my blog이 최근의 경험에 대해 자세히 설명해주었습니다. 일반적으로 스레드를 의미하는 입력 또는 출력 스트림을 클라이언트에 모든 언어로 연결하지 않으려합니다. 콜백을 사용하여 점진적으로 데이터를 전달할 수 있습니다.

6

JNI를 통해 Java OutputStream에 대한 쓰기 작업을 플러시하기 전에 (일부 설정 크기까지) 버퍼링하는 C++ ostream을 구현할 것입니다.

자바 측에서는 일반적인 OutputStream 인스턴스를 사용할 수도 있고, 스레드 간의 잠금 경합을 피하기 위해 버퍼 블록 (본질적으로 byte [])의 큐를 구현할 수도 있습니다. 실제 출력 스트림은 대기열에서 블록을 가져 와서 OutpuStream에 쓰는 다른 스레드의 작업에서만 사용됩니다.이것이 필요한지 아닌지를이 세부 수준에서 말할 수는 없습니다. JNI 작품의 출력 스트림에 직접 글을 쓸 수 있습니다.

나는 다른 포스터 관련 문제를 JNI와 공유하지 않으며 JNI를 사용하는 데는 아무런 문제가 없습니다. 물론, 유지 보수 담당자는 자신의 물건을 알아야 할 것입니다.하지만 그에 관한 내용이며 Java/C++ 계층의 복잡성은 문서, 예제 및 테스트 케이스로 관리 할 수 ​​있습니다. 이전에는 Java <> 퍼포먼스, 스레딩 또는 유지 관리에 문제가없는 COM 인터페이스를 사용하여 COM 브리지를 구현했습니다.

완전히 자유로운 선택을 감안할 때 JNI는 없지만 나에게 있어서는 호환되지 않는 시스템과의 긴밀한 통합을 가능하게함으로써 그 날을 구했습니다.

+0

JNI를 강타하지 않는 보너스 포인트. – rdb