- - PR -
JNI のGetArrayLengthでNULLの値を渡すとどうなりますか?
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2004-12-27 15:10
tomomoです。お世話になります。 JNIを使って、次のようなコードを書きました。 この時、javaからjarybDataがNULLのデータを渡してしまうと、javaプロセスが ダウンします。 ここで質問なのですが、GetArrayLengthにNULLのデータを渡してしまった場合、 どうなるのでしょうか? 私は、戻り値がNULLで値が帰ってくると思っていましたが、この認識が間違い なのでしょうか? javaがダウンするが正しい事で、きちんとNULLの判断をしてあがないといけな いものなのでしょうか? 大変申し訳ございませんが、ご存知の方がいましたら教えてください。 以下、byte配列からcharに変換するC言語のコードです。 char* byteArray2char( JNIEnv* i_jEnv, jbyteArray jarybData, unsigned int *size) { char* cpData; jsize jszArray; jszArray = (*i_jEnv)->GetArrayLength( i_jEnv, jarybData ); if ( !jszArray ) return (char*)NULL; cpData=(char *)malloc(jszArray+10); if ( !(cpData) ) return (char*)NULL; (*i_jEnv)->GetByteArrayRegion( i_jEnv, jarybData, 0, jszArray, (char *)cpData ); cpData[jszArray] = (char)NULL; *size = jszArray; return cpData; } | ||||||||
|
投稿日時: 2004-12-27 15:15
tomomoです。
すみません、環境を書くのを忘れていました。 redhat ESL 3.0 java 1.4.2_06 です。 よろしくお願い致します。 | ||||||||
|
投稿日時: 2004-12-27 16:19
うろ覚えですが、jsize はポインターではないので、GetArrayLengthはNULLを返す事はないと思います。調べてないので分かりませんが、-1とかを返しているのではないでしょうか。
ちなみに・・・ NULLは普通「0」なので、NULLの0と長さの0(空配列)が重なってしまうような値をGetArrayLengthは返さないはずです。 | ||||||||
|
投稿日時: 2004-12-28 16:16
H2さん、返信ありがとうございます。
NULL値が返ってくるのも辺ですね。 ただ、次のようなプログラムを作ったのですが、 GetArrayLengthの引数がNULLだと、javaがハング してしまうようです。 これが正しい動作なのか、ご存知の方がいましたら 教えてください。 <><><><> # cat HelloJNI.java public class HelloJNI{ public native void sayHello(); static{ System.loadLibrary("hellojni"); } public static void main(String[] args){ HelloJNI hello = new HelloJNI(); hello.sayHello(); } } <><><><> # cat HelloJNI.h /* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class HelloJNI */ #ifndef _Included_HelloJNI #define _Included_HelloJNI #ifdef __cplusplus extern "C" { #endif /* * Class: HelloJNI * Method: sayHello * Signature: ()V */ JNIEXPORT void JNICALL Java_HelloJNI_sayHello (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif <><><><> # cat HelloJNI.c #include "HelloJNI.h" JNIEXPORT void JNICALL Java_HelloJNI_sayHello (JNIEnv *env, jobject this) { jsize jszArray; jbyteArray jarybData=NULL; printf("Hello, JNI (Java Native Interface)...\n"); jszArray = (*env)->GetArrayLength( env, jarybData ); printf("Hello, JNI (Java Native Interface)...END\n"); } <><><><> 上記のコードで、 # java HelloJNI と実行すると、次の様にjavaがabortします。 Hello, JNI (Java Native Interface)... Unexpected Signal : 11 occurred at PC=0xB722838C Function=(null) Library=/data/usr/local/j2sdk1.4.2_06/jre/lib/i386/client/libjvm.so NOTE: We are unable to locate the function name symbol for the error just occurred. Please refer to release documentation for possible reason and solutions. Current Java thread: at HelloJNI.sayHello(Native Method) at HelloJNI.main(HelloJNI.java:11) Dynamic libraries: 08048000-08056000 r-xp 00000000 03:04 741616 /data/usr/local/j2sdk1.4.2_06/bin/java 08056000-08059000 rw-p 0000d000 03:04 741616 /data/usr/local/j2sdk1.4.2_06/bin/java aa6f4000-aa6f5000 r-xp 00000000 03:02 1279426 /root/java_src/libhellojni.so aa6f5000-aa6f6000 rw-p 00000000 03:02 1279426 /root/java_src/libhellojni.so aa6f6000-aa7b2000 r--s 00000000 03:04 307046 /data/usr/local/j2sdk1.4.2_06/jre/lib/ext/localedata.jar aa7b2000-aa7bf000 r--s 00000000 03:04 307015 /data/usr/local/j2sdk1.4.2_06/jre/lib/ext/ldapsec.jar aa7bf000-aa7c2000 r--s 00000000 03:04 307013 /data/usr/local/j2sdk1.4.2_06/jre/lib/ext/dnsns.jar aa7c2000-aa7de000 r--s 00000000 03:04 307012 /data/usr/local/j2sdk1.4.2_06/jre/lib/ext/sunjce_provider.jar aa9e2000-aaabd000 r--p 00e76000 03:02 688180 /usr/lib/locale/locale-archive aaabd000-aacbd000 r--p 00000000 03:02 688180 /usr/lib/locale/locale-archive b4f6c000-b54c5000 r--s 00000000 03:04 194385 /data/usr/local/j2sdk1.4.2_06/jre/lib/charsets.jar b54c5000-b54d6000 r--s 00000000 03:04 194340 /data/usr/local/j2sdk1.4.2_06/jre/lib/jce.jar b54d6000-b55b3000 r--s 00000000 03:04 194384 /data/usr/local/j2sdk1.4.2_06/jre/lib/jsse.jar b55b3000-b55c9000 r--s 00000000 03:04 194339 /data/usr/local/j2sdk1.4.2_06/jre/lib/sunrsasign.jar b5613000-b6fba000 r--s 00000000 03:04 194387 /data/usr/local/j2sdk1.4.2_06/jre/lib/rt.jar b6fba000-b6fce000 r-xp 00000000 03:04 226518 /data/usr/local/j2sdk1.4.2_06/jre/lib/i386/libzip.so b6fce000-b6fd1000 rw-p 00013000 03:04 226518 /data/usr/local/j2sdk1.4.2_06/jre/lib/i386/libzip.so b6fd1000-b6ff1000 r-xp 00000000 03:04 226516 /data/usr/local/j2sdk1.4.2_06/jre/lib/i386/libjava.so b6ff1000-b6ff3000 rw-p 0001f000 03:04 226516 /data/usr/local/j2sdk1.4.2_06/jre/lib/i386/libjava.so b6ff3000-b7003000 r-xp 00000000 03:04 226515 /data/usr/local/j2sdk1.4.2_06/jre/lib/i386/libverify.so b7003000-b7005000 rw-p 0000f000 03:04 226515 /data/usr/local/j2sdk1.4.2_06/jre/lib/i386/libverify.so b7005000-b7010000 r-xp 00000000 03:02 524378 /lib/libnss_files-2.3.2.so b7010000-b7011000 rw-p 0000a000 03:02 524378 /lib/libnss_files-2.3.2.so b701c000-b7020000 rw-s 00000000 03:02 1279427 /tmp/hsperfdata_root/6094 b7020000-b7041000 r-xp 00000000 03:02 1015865 /lib/tls/libm-2.3.2.so b7041000-b7042000 rw-p 00020000 03:02 1015865 /lib/tls/libm-2.3.2.so b7042000-b7054000 r-xp 00000000 03:02 524362 /lib/libnsl-2.3.2.so b7054000-b7055000 rw-p 00011000 03:02 524362 /lib/libnsl-2.3.2.so b705d000-b7065000 r-xp 00000000 03:04 226504 /data/usr/local/j2sdk1.4.2_06/jre/lib/i386/native_threads/libhpi.so b7065000-b7066000 rw-p 00007000 03:04 226504 /data/usr/local/j2sdk1.4.2_06/jre/lib/i386/native_threads/libhpi.so b7066000-b7462000 r-xp 00000000 03:04 226510 /data/usr/local/j2sdk1.4.2_06/jre/lib/i386/client/libjvm.so b7462000-b747e000 rw-p 003fb000 03:04 226510 /data/usr/local/j2sdk1.4.2_06/jre/lib/i386/client/libjvm.so b7491000-b75c2000 r-xp 00000000 03:02 1015863 /lib/tls/libc-2.3.2.so b75c2000-b75c5000 rw-p 00130000 03:02 1015863 /lib/tls/libc-2.3.2.so b75c8000-b75ca000 r-xp 00000000 03:02 524358 /lib/libdl-2.3.2.so b75ca000-b75cb000 rw-p 00001000 03:02 524358 /lib/libdl-2.3.2.so b75cb000-b75d8000 r-xp 00000000 03:02 1015867 /lib/tls/libpthread-0.60.so b75d8000-b75d9000 rw-p 0000c000 03:02 1015867 /lib/tls/libpthread-0.60.so b75eb000-b7600000 r-xp 00000000 03:02 524345 /lib/ld-2.3.2.so b7600000-b7601000 rw-p 00015000 03:02 524345 /lib/ld-2.3.2.so Heap at VM Abort: Heap def new generation total 576K, used 136K [0xaaec0000, 0xaaf60000, 0xab3a0000) eden space 512K, 26% used [0xaaec0000, 0xaaee21c8, 0xaaf40000) from space 64K, 0% used [0xaaf40000, 0xaaf40000, 0xaaf50000) to space 64K, 0% used [0xaaf50000, 0xaaf50000, 0xaaf60000) tenured generation total 1408K, used 0K [0xab3a0000, 0xab500000, 0xaeec0000) the space 1408K, 0% used [0xab3a0000, 0xab3a0000, 0xab3a0200, 0xab500000) compacting perm gen total 4096K, used 1171K [0xaeec0000, 0xaf2c0000, 0xb2ec0000) the space 4096K, 28% used [0xaeec0000, 0xaefe4ff0, 0xaefe5000, 0xaf2c0000) Local Time = Tue Dec 28 15:42:10 2004 Elapsed Time = 0 # # HotSpot Virtual Machine Error : 11 # Error ID : 4F530E43505002EF # Please report this error at # http://java.sun.com/cgi-bin/bugreport.cgi # # Java VM: Java HotSpot(TM) Client VM (1.4.2_06-b03 mixed mode) # # An error report file has been saved as hs_err_pid6094.log. # Please refer to the file for further information. # アボートしました | ||||||||
|
投稿日時: 2004-12-28 17:59
私も試してみました。GetArrayLengthにNULLを渡すとクラッシュするみたいですね。ドキュメントにはNULLを渡した場合どうなるか書いてないんですけどね。
ちなみに解決法は簡単です。 [code] char* byteArray2char( JNIEnv* i_jEnv, jbyteArray jarybData, unsigned int *size) { char* cpData; jsize jszArray; //arrayがNULLならNULLを返す。 if (jarybData==NULL) return (char*)NULL; jszArray = (*i_jEnv)->GetArrayLength( i_jEnv, jarybData ); if ( !jszArray ) return (char*)NULL; cpData=(char *)malloc(jszArray+10); if ( !(cpData) ) return (char*)NULL; (*i_jEnv)->GetByteArrayRegion( i_jEnv, jarybData, 0, jszArray, (char *)cpData ); cpData[jszArray] = (char)NULL; *size = jszArray; return cpData; } | ||||||||
|
投稿日時: 2004-12-28 18:20
H2さん。こんばんは。
そうですね。NULLチェックするのが良いのでしょうね。。 ありがとうございました。 | ||||||||
|
投稿日時: 2004-12-28 21:21
H2様、
Java Native Interface 仕様の『プログラミングエラーの報告』には その理由も含めて明記されていますよ。 | ||||||||
|
投稿日時: 2004-12-28 21:58
一応読んではいたのですが、そこで書かれている事はJNIで用意されている関数の事ではないと思います。あ、でも私の思い違いかもしれないです ![]() http://java.sun.com/j2se/1.4.2/docs/guide/jni/spec/functions.html#wp17314 にはNULLの場合どうなるかは書いていません。できればこっちに書いてほしかったなぁ > Sun様 |