안녕하세요.
JNI를 이용해서 소켓통신을 하려고 합니다.
TCP방식으로 서버에 헤더를 주고 받으면서 마지막에 데이터를 받으려고 합니다.
받는 데이터는 바이트배열로 되어 있는데...
이것이 문제입니다.
바이트 배열 크기가 몇인지 모르기 때문에 JAVA내에서 초기화를 NULL로 해놓고
JNI 코드 내에서 적정 크기로 할당을 해야하는데..
이 부분이 되지 않습니다.
사용한 코드는 다음과 같습니다.
-- JAVA
byte[] btRecvData = null;
-- C
recvLength = getDataWithSocketHeader( conn, hd, (void**)&recvData, &nErr);
//Java에서 사용할 byte배열 객체 메모리 할당
btRecvData = (env)->NewByteArray(recvLength);
(env)->SetByteArrayRegion(btRecvData, 0, recvLength, (jbyte *)((byte*)recvData));
lRecvSize = (jlong)recvLength;
getDataWithSocketHeader() 함수를 통해서 recvData에 바이트 배열 데이터(JNI 내부에서 만든 C에서 사용하는 char[])
에 전달받은 데이터를 저장하고 해당 데이터를 JNI 함수 인자로 값을 복사하려고 합니다.
그래서 전달받은 데이터 사이즈 만큼 byteArray를 할당하려고
btRecvData = (env)->NewByteArray(recvLength);
를 사용하지만 실제적으로 NULL값이 생성됩니다.
혹시나 해서 recvLength 값을 검사해보면 실제 데이터 크기를 나타냅니다.
이를 해결하려면 JAVA에서 바이트배열을 버퍼로 할당해 놓고 사용하면 되기는 하지만...
역시 불필요한 용량을 또는 부족한 용량이 될 가능성이 있어서 좋지 않은 방법입니다.
이를 어떻게 해야 하나요?
왜 ByteArray를 할당해도 할당이 되지 않는 건가요??;;;;;
본래 JNI 호출되는 함수선언은 다음과 같습니다.
private static native boolean getData( String szIP, int nPort, short wRetry, int nInterval, int nCmd, String strSendData, long lSendSize, byte[] btRecvData, long lRecvSize, int nError );
생명의돌 님 말씀처럼 리턴값으로 byte[]로 하면 잘됩니다.
private static native byte[] getData( String szIP, int nPort, short wRetry, int nInterval, int nCmd, String strSendData, long lSendSize, long lRecvSize,
int nError );
그런데 왜 처음에 제가 하려던 방식이 안되는 것인지 궁금합니다.




NewByteArray 로 새로운 자바어레이를 생성해서 자바에게 리턴값으로 돌려주면 어떨까요?
굳이 null 인 값을 C++에서 사용할 이유는 없어보이는데요 ^^