처리 비용을 줄이기 위해 JNI에서 오디오 신호를 처리해야하는 저수준 Android 라이브러리를 개발 중입니다. 같은 오디오 버퍼를 여러 번 참조해야 할 수도 있으므로 구조체의 포인터를 C로 랩핑하여 여러 오디오 버퍼를 동일한 오디오 버퍼에 액세스 할 수 있습니다. 나는 주로 here과 here에서 빌린 아이디어를 사용합니다.JNI/Android-NDK에서 포인터를 jlong으로 전달하지 않음()
그러나 예상대로 작동하지 않습니다. 다른 함수가 이전 jni 호출에 의해 할당 된 메모리에 액세스하려고 시도한 후 내 프로그램이 중단됩니다.
이struct AddAudioRet{
int chCnt;
int traceCnt;
int sampleCnt;
float ***data; // data[chIdx][traceIdx][sampleIdx]; -> reverse order of the Matlab data structure
};
extern "C" jlong Java_XXX_XXX_addAudioSamples(JNIEnv *env, jobject obj, jbyteArray audioToAdd) {
// some processing codes
AddAudioRet *ret;
ret = (AddAudioRet *)malloc(sizeof(AddAudioRet));
ret->chCnt = ps->recordChCnt; // 2
ret->traceCnt = repeatToProcess; // 3
ret->sampleCnt = as->signalSize; // 2400
jlong retLong = (jlong)ret;
mylog("retLong (jlong) = %ld", retLong);
AddAudioRet *temp = (AddAudioRet *)retLong;
mylog("temp's chCnt %d, traceCnt %d, sampleCnt = %d", temp->chCnt, temp->traceCnt, temp->sampleCnt);
return retLong; // return the memory address of the ret structure
}
extern "C" void Java_XXX_XXX_debugDumpAddAudioRet(JNIEnv *env, jobject obj, jlong addAudioRet) {
debug("addAudioRetLong = %ld", addAudioRet);
debug("ret's chCnt %d, traceCnt %d, sampleCnt = %d", r->chCnt, r->traceCnt, r->sampleCnt);
}
안드로이드, 나는이 같은 JNI 함수를 호출 :
public native int addAudioSamples(byte[] audioToAdd);
public native void debugDumpAddAudioRet(long addAudioRet);
int testJNI(byte[] data) {
long ret = addAudioSamples(data);
debugDumpAddAudioRet(ret);
}
결과 : 내가 아는
retLong (jlong) = 547383410656
temp's chCnt 2, traceCnt 3, sampleCnt = 2400
// *** dumped by the debug check ***
addAudioRetLong = 1922564064
ret's chCnt 55646750, traceCnt 82374663, sampleCnt = 1831675530
여기
이 문제를 표시하는 JNI의 예입니다 문제는 메모리 주소 출력이 동일하지 않기 때문에 메모리 주소와 jlong 간의 형식 변환입니다. 그러나 변환이 허용되지 않거나 합법적 인 경우 어떻게 발생하는지 모릅니다. (임시적으로) "temp"변수를 덤프 할 때 오류가 발생합니다. 맞습니까?
크기 문제 일 수 있습니다. 포인터는 64 비트이지만 긴 포인터는 32 비트 만 사용하는 경향이 있습니다. 일반적으로 포인터를 저장하려면 긴 길이를 사용해야합니다. –
안녕하세요 게이브, 난 크기 문제도 같아요,하지만 sizeof jlong (= 8 바이트) 인쇄 한 및 특정 Java 긴 것입니다> 8 바이트뿐만 아니라 (예, 긴 testLong = 547383410656L 괜찮습니다.). –