2010-01-04 5 views
7

C에서 일부 메모리를 할당하고 다음과 같이 java 객체 인스턴스와 연결하고 싶습니다.Java JNI - C에 할당 된 자원을 Java 객체와 연관 시키는가?

void configure(JNIEnv *object, jobject obj, ....) { 
    char *buf = new char[1024]; 
    // associated <buf> with <obj> somehow 
} 

그리고 나서 Java 객체가 가비지 수집 될 때 메모리를 해제합니다. JNI 함수는 Java 객체의 finalize() 메소드에서 작동합니다.

질문은 C 포인터를 자바 객체와 어떻게 연관 시키는가입니다. 개체에 필드를 유지하고 포인터를 캐스팅 할? 더 좋은 방법이 있습니까?

+2

dup : http://stackoverflow.com/questions/214699/jni-memory-management-using-the-invocation-api – falstro

+0

이 질문에서 일종의 C 객체를 자바 인스턴스. 제시된 예제에서 포인터는 길게 형변환됩니다. 이것이 유일한 방법입니까? – Viktor

답변

16

일반적으로 C에서 Java로 포인터를 전송하려면 long을 사용하여 플랫폼이 64 비트 인 경우 포인터 값을 저장할 수있는 비트가 충분하도록하는 것이 좋습니다. 이어서

는 다음 JNI 기능에 jobject로 전달이 JNI 기능 내부 참고 자바 측으로부터 이러한 직접적인 ByteBuffer을 할당 할 수있는 메모리 C. 공유 할 수 ByteBuffer 인스턴스를 생성 ByteBuffer.allocateDirect()를 보라 GetDirectBufferAddress 기능을 사용합니다.

또 다른 방법은 네이티브 측에서 NewDirectByteBuffer JNI 기능을 사용하여 메모리의 기본 영역을 래핑하는 것입니다. 그것은 당신에게 jobject을 자바 측으로 돌려 보낸다 (로컬 참조와 글로벌 참조에주의하라). 네이티브 메모리를 래핑하는 직접 ByteBuffer이 생성되면 네이티브 메모리를 관리해야합니다. 즉,을 네이티브 코드로 호출해야합니다. Java는이를 수행하지 않습니다. 너를 위해서.

+0

고마워요! 내가 올바르게 이해한다면, ByteBuffer.allocateDirect()를 사용하면 + 메모리 관리를 통과하는 포인터가 회피된다. 이 방법은 ByteBuffer가 메모리를 관리합니다. – Viktor

+1

Java 측에서 직접 ByteBuffer를 할당하면 Java가 메모리 블록을 할당하게됩니다.이 블록은'finalize '가 실행될 때 해제 될 것입니다. 유일한 단점은 가비지 수집기가 전달되는시기를 정확하게 알지 못하므로 버퍼가 완료된 후 메모리가 해제되는 시점을 알 수 없다는 것입니다. –

+0

+1 깔끔함! 좋은 대답. – JesperE

0

Java에는 네이티브 포인터 개념이 없으므로 long으로 저장하는 것이 유일한 실제 옵션입니다. 그러나 finalize을 사용하여 포인터를 비우지 않아야합니다. finalize 메소드는 리소스를 정리하는 수단으로 신뢰할 수 없습니다. 자세한 내용은 this question을 참조하십시오.

관련 문제