과 같은 구현 세부 정보는 의도적으로 제외됩니다. method1은 closable을 캡처합니까?이 질문의 첫 번째 부분에 나와 있습니다.
static char* value;
void capture(char* ptr){
value = ptr;
}
int len(void) {
return strlen(value);
}
이 네이티브 라이브러리가
interface CApi extends Library {
static {
Native.register("test.so", CApi.class)
}
void capture(Pointer s);
int test();
}
JNA
를 사용하여 포장한다 : 내가 같이 요약 될 수있는 C 라이브러리가:
내 spefic 사용 사례는 이것이다 그리고 내 원래 클라이언트 코드는 다음과 같습니다.
cApi = Native.loadLibrary("test.so", CApi.class);
byte[] data = Native.toByteArray("foo");
Memory m = new Memory(data.length + 1);
m.write(0, data, 0, data.length);
m.setByte(data.length, (byte)0);
cApi.capture(m);
System.out.print(cApi.len());
이 첫 번째 버전의 문제는 m
이 Java에서 할당되었으며이 메모리의 수명주기가 매우 가까워서 m
에 연결되어 있다는 것입니다. 에서 GC의 차기
내가 JNA의 Memory
AutoClosableMemory
을 소개하는 서브 클래스 제안이를 방지하기 위해 (JNA는 기본 메모리를 확보 할 수 finalize
에 의존) 때 capture(m)
메모리가 해제됩니다 일단 m
는 더 이상 강력하게 도달 할 수 없습니다. 아이디어는 리소스를 사용하는 try를 사용하면 자원이이 범위 내에서 강하게 도달 할 수 있음을 분명하게 나타냅니다. 우리가 네이티브 메모리를 해제 할 수 있다는 보너스는 곧 GC를 기다릴 필요없이 더 이상 필요하지 않게되었습니다 (이봐, RAII입니다!).
try (AutoClosableMemory m = [...]) {
cApi.capture(m);
cApi.test();
}
오전 나는 m.close()
이 cApi.test()
전 m
강력하게 연결할 수 있는지 호출되지 않습니다 보장? 이 경우 m
은 기본 C API에 의해 캡처되지만 Java 컴파일러는이를 알 수 없습니다.
'네이티브 명령어 주위에 코드를 재정렬하지 않는다'와 같은 것을 찾고있었습니다. 그 링크가 있습니까? – Oleg
네이티브 코드 블록은 JLS에서 외부 작업으로 공식화됩니다. 그들은 이전 코드와 후속 코드와의 관계 이전에 일어난 일을 암시합니다. 나는이 프리젠 테이션을 통해 도움이 될만한 정보를 얻었습니다. https://youtu.be/XgiXKPEILoc 40 분에 외부 행동에 대해 이야기합니다. –
감사합니다. 나는 당신이 당신의 대답에 그것을 덧붙여 야한다고 생각합니다. [여기] (https://youtu.be/XgiXKPEILoc?t=40m37s)에서 OP의 질문에 대해 자세히 설명합니다. – Oleg