环境 Ubuntu12.04 + openJDK6
JNI中使用“修改的UTF8”编码,而Linux下wchar_t使用UTF32,注意转码。
Java代码
1public class JavaCode {
2
3 public native void cVoid();
4 public native static void cVoidStatic();
5
6 public native int cPassRuturnInt( int i );
7
8 public native void cPassString( String msg );
9 public native String cReturnString();
10
11 public native void cPassIntArray( int[] ia );
12 public native int[] cReturnIntArray();
13
14 public native void cPassObject( JavaStruct js );
15 public native JavaStruct cReturnObject();
16
17 public native void cPassObjectArray( JavaStruct[] jsa );
18 public native JavaStruct[] cReturnObjectArray();
19
20 static {
21 System.loadLibrary("cCode");
22 }
23
24 public static void main( String[] args ) {
25 /**//*
26 {
27 System.err.println( "++++++++cVoidStatic" );
28 cVoidStatic();
29 System.err.println();
30 }
31 */
32
33 JavaCode jc = new JavaCode();
34
35 /**//*
36 {
37 System.err.println( "++++++++cVoid" );
38 jc.cVoid();
39 System.err.println();
40 }
41 */
42
43 /**//*
44 {
45 System.err.println( "++++++++cPassRuturnInt" );
46 int i = 1;
47 System.err.println( "++++i = " + i );
48 i = jc.cPassRuturnInt( i );
49 System.err.println( "++++i = " + i );
50 System.err.println();
51 }
52 */
53
54 /**//*
55 {
56 System.err.println( "++++++++cPassString" );
57 String str = "hello中国";
58 System.err.println( "++++" + str );
59 System.err.print( "++++" );
60 for ( int i = 0; i < str.length(); ++i ) {
61 System.err.print( (int)str.charAt(i) + " " );
62 }
63 System.err.println();
64 jc.cPassString( str );
65 System.err.println();
66 }
67 */
68
69 {
70 System.err.println( "++++++++cReturnString" );
71 String str = jc.cReturnString();
72 System.err.println( "++++" + str );
73 System.err.print( "++++" );
74 for ( int i = 0; i < str.length(); ++i ) {
75 System.err.print( (int)str.charAt(i) + " " );
76 }
77 System.err.println();
78 System.err.println();
79 }
80
81 /**//*
82 {
83 System.err.println( "++++++++cPassIntArray" );
84 int[] ia = new int[]{ 1, 2, 3, 4 };
85 System.err.print( "++++" );
86 for ( int i = 0; i < ia.length; ++i ) {
87 System.err.print( ia[i] + " " );
88 }
89 System.err.println();
90 jc.cPassIntArray( ia );
91 System.err.print( "++++" );
92 for ( int i = 0; i < ia.length; ++i ) {
93 System.err.print( ia[i] + " " );
94 }
95 System.err.println();
96 System.err.println();
97 }
98 */
99
100 /**//*
101 {
102 System.err.println( "++++++++cReturnIntArray" );
103 int[] ia = jc.cReturnIntArray();
104 System.err.print( "++++" );
105 for ( int i = 0; i < ia.length; ++i ) {
106 System.err.print( ia[i] + " " );
107 }
108 System.err.println();
109 System.err.println();
110 }
111 */
112
113 /**//*
114 {
115 System.err.println( "++++++++cPassObject" );
116 JavaStruct js = new JavaStruct();
117 js.i = 1;
118 js.str = "hello上海20001112华东师范大学ECNU";
119 js.ia = new int[10];
120 js.ia[0] = 20;
121 System.err.println( "++++js.i = " + js.i +
122 " js.str = \"" + js.str + "\"" +
123 " js.ia[0] = " + js.ia[0] );
124 jc.cPassObject( js );
125 System.err.println( "++++js.i = " + js.i +
126 " js.str = \"" + js.str + "\"" +
127 " js.ia[0] = " + js.ia[0] );
128 }
129 */
130
131 {
132 System.err.println( "++++++++cPassObjectArray" );
133 JavaStruct[] jsa = new JavaStruct[10];
134 for ( int i = 0; i < 10; ++i ) {
135 jsa[i] = new JavaStruct();
136 }
137 jsa[1].i = 7;
138 jsa[1].str = "科学院";
139 jsa[1].ia = new int[10];
140 jsa[1].ia[0] = 19;
141 System.err.println( "++++jsa[1].i = " + jsa[1].i +
142 " jsa[1].str = \"" + jsa[1].str + "\"" +
143 " jsa[1].ia[0] = " + jsa[1].ia[0] );
144 jc.cPassObjectArray( jsa );
145 System.err.println( "++++jsa[1].i = " + jsa[1].i +
146 " jsa[1].str = \"" + jsa[1].str + "\"" +
147 " jsa[1].ia[0] = " + jsa[1].ia[0] );
148 }
149
150 /**//*
151 System.err.println( "++++++++" );
152 */
153 }
154
155}
156
157class JavaStruct {
158 public int i;
159 public String str;
160 public int[] ia;
161}
162
163 生成的C头文件
1/**//* DO NOT EDIT THIS FILE - it is machine generated */
2#include <jni.h>
3/**//* Header for class JavaCode */
4
5#ifndef _Included_JavaCode
6#define _Included_JavaCode
7#ifdef __cplusplus
8extern "C" {
9#endif
10/**//*
11 * Class: JavaCode
12 * Method: cVoid
13 * Signature: ()V
14 */
15JNIEXPORT void JNICALL Java_JavaCode_cVoid
16 (JNIEnv *, jobject);
17
18/**//*
19 * Class: JavaCode
20 * Method: cVoidStatic
21 * Signature: ()V
22 */
23JNIEXPORT void JNICALL Java_JavaCode_cVoidStatic
24 (JNIEnv *, jclass);
25
26/**//*
27 * Class: JavaCode
28 * Method: cPassRuturnInt
29 * Signature: (I)I
30 */
31JNIEXPORT jint JNICALL Java_JavaCode_cPassRuturnInt
32 (JNIEnv *, jobject, jint);
33
34/**//*
35 * Class: JavaCode
36 * Method: cPassString
37 * Signature: (Ljava/lang/String;)V
38 */
39JNIEXPORT void JNICALL Java_JavaCode_cPassString
40 (JNIEnv *, jobject, jstring);
41
42/**//*
43 * Class: JavaCode
44 * Method: cReturnString
45 * Signature: ()Ljava/lang/String;
46 */
47JNIEXPORT jstring JNICALL Java_JavaCode_cReturnString
48 (JNIEnv *, jobject);
49
50/**//*
51 * Class: JavaCode
52 * Method: cPassIntArray
53 * Signature: ([I)V
54 */
55JNIEXPORT void JNICALL Java_JavaCode_cPassIntArray
56 (JNIEnv *, jobject, jintArray);
57
58/**//*
59 * Class: JavaCode
60 * Method: cReturnIntArray
61 * Signature: ()[I
62 */
63JNIEXPORT jintArray JNICALL Java_JavaCode_cReturnIntArray
64 (JNIEnv *, jobject);
65
66/**//*
67 * Class: JavaCode
68 * Method: cPassObject
69 * Signature: (LJavaStruct;)V
70 */
71JNIEXPORT void JNICALL Java_JavaCode_cPassObject
72 (JNIEnv *, jobject, jobject);
73
74/**//*
75 * Class: JavaCode
76 * Method: cReturnObject
77 * Signature: ()LJavaStruct;
78 */
79JNIEXPORT jobject JNICALL Java_JavaCode_cReturnObject
80 (JNIEnv *, jobject);
81
82/**//*
83 * Class: JavaCode
84 * Method: cPassObjectArray
85 * Signature: ([LJavaStruct;)V
86 */
87JNIEXPORT void JNICALL Java_JavaCode_cPassObjectArray
88 (JNIEnv *, jobject, jobjectArray);
89
90/**//*
91 * Class: JavaCode
92 * Method: cReturnObjectArray
93 * Signature: ()[LJavaStruct;
94 */
95JNIEXPORT jobjectArray JNICALL Java_JavaCode_cReturnObjectArray
96 (JNIEnv *, jobject);
97
98#ifdef __cplusplus
99}
100#endif
101#endif
102 C代码
1#include <jni.h>
2#include "JavaCode.h"
3#include <stdio.h>
4#include <wchar.h>
5#include "cvt_mutf8_utf32.h"
6
7
8/**//*
9 * Class: JavaCode
10 * Method: cVoid
11 * Signature: ()V
12 */
13JNIEXPORT void JNICALL Java_JavaCode_cVoid
14(JNIEnv *env, jobject obj) {
15 fprintf( stderr, "--------Java_JavaCode_cVoid\n" );
16 return;
17}
18
19/**//*
20 * Class: JavaCode
21 * Method: cVoidStatic
22 * Signature: ()V
23 */
24JNIEXPORT void JNICALL Java_JavaCode_cVoidStatic
25(JNIEnv *env, jclass jcls) {
26 fprintf( stderr, "--------Java_JavaCode_cVoidStatic\n" );
27 return;
28}
29
30/**//*
31 * Class: JavaCode
32 * Method: cPassRuturnInt
33 * Signature: (I)I
34 */
35JNIEXPORT jint JNICALL Java_JavaCode_cPassRuturnInt
36(JNIEnv *env, jobject obj, jint i) {
37 fprintf( stderr, "--------Java_JavaCode_cPassRuturnInt\n" );
38 fprintf( stderr, "----i = %d; ++i; return %d\n", i, i+1 );
39 return i+1;
40}
41
42/**//*
43 * Class: JavaCode
44 * Method: cPassString
45 * Signature: (Ljava/lang/String;)V
46 */
47JNIEXPORT void JNICALL Java_JavaCode_cPassString
48(JNIEnv *env, jobject obj, jstring jstr) {
49 fprintf( stderr, "--------Java_JavaCode_cPassString\n" );
50 jsize len = (*env)->GetStringUTFLength( env, jstr );
51 const char * str = (*env)->GetStringUTFChars( env, jstr, NULL );
52 fprintf( stderr, "----utf8 len = %d, str = \"%s\"\n", len, str );
53 fprintf( stderr, "----" );
54 int i;
55 for ( i = 0; i < len; ++i ) {
56 fprintf( stderr, "%x ", (int)(*((const unsigned char*)str+i)) );
57 }
58 fprintf( stderr, "\n" );
59
60 fprintf( stderr, "----sizeof(wchar_t) == %d\n", sizeof(wchar_t) );
61 wchar_t wstr[ 100 ];
62 int wlen;
63 wlen = mutf8_to_utf32( (const unsigned char*)str,
64 (unsigned int*)wstr, 100 );
65 fprintf( stderr, "----mutf8_to_utf32 wlen = %d, ", wlen );
66 for ( i = 0; i < wlen; ++i ) {
67 fprintf( stderr, "%d ", (unsigned int)wstr[i] );
68 }
69 fprintf( stderr, "\n" );
70 wcscpy( wstr, L"hello中国" );
71 wlen = wcslen( wstr );
72 fprintf( stderr, "----wcscpy wlen = %d, ", wlen );
73 for ( i = 0; i < wlen; ++i ) {
74 fprintf( stderr, "%d ", (unsigned int)wstr[i] );
75 }
76 fprintf( stderr, "\n" );
77 (*env)->ReleaseStringUTFChars( env, jstr, str );
78 return;
79}
80
81/**//*
82 * Class: JavaCode
83 * Method: cReturnString
84 * Signature: ()Ljava/lang/String;
85 */
86JNIEXPORT jstring JNICALL Java_JavaCode_cReturnString
87(JNIEnv *env, jobject obj) {
88 fprintf( stderr, "--------Java_JavaCode_cReturnString\n" );
89 wchar_t wstr[] = L"你好good!";
90 int wlen = wcslen( wstr );
91 char mutf8[ 100 ];
92 int len;
93 int i;
94 fprintf( stderr, "----wchar_t wlen = %d, ", wlen );
95 for ( i = 0; i < wlen; ++i ) {
96 fprintf( stderr, "%d ", (int)wstr[i] );
97 }
98 fprintf( stderr, "\n" );
99
100 len = utf32_to_mutf8( (const unsigned int*)wstr,
101 (unsigned char*)mutf8, 100 );
102 fprintf( stderr, "----utf32_to_mutf8 len = %d, ", len );
103 for ( i = 0; i < len; ++i ) {
104 fprintf( stderr, "%d ", (int)mutf8[i] );
105 }
106 fprintf( stderr, "\n" );
107 fprintf( stderr, "----%s\n", mutf8 );
108
109 jstring jstr = (*env)->NewStringUTF( env, mutf8 );
110 return jstr;
111}
112
113/**//*
114 * Class: JavaCode
115 * Method: cPassIntArray
116 * Signature: ([I)V
117 */
118JNIEXPORT void JNICALL Java_JavaCode_cPassIntArray
119(JNIEnv *env, jobject obj, jintArray ia ) {
120 int i;
121 jint len, *arr;
122 fprintf( stderr, "--------Java_JavaCode_cPassIntArray\n" );
123 len = (*env)->GetArrayLength( env, ia );
124 arr = (*env)->GetIntArrayElements( env, ia, NULL );
125 if ( NULL == arr ) {
126 fprintf( stderr, "----GetIntArrayElements failed\n" );
127 (*env)->ReleaseIntArrayElements( env, ia, arr, 0 );
128 return;
129 }
130 fprintf( stderr, "----int array length = %d\n----elem =", len );
131 for ( i = 0; i < len; ++i ) {
132 fprintf( stderr, " %d", arr[i] );
133 }
134 fprintf( stderr, "\n----modify\n----elem =" );
135 for ( i = 0; i < len; ++i ) {
136 fprintf( stderr, " %d", ++arr[i] );
137 }
138 fprintf( stderr, "\n" );
139 (*env)->ReleaseIntArrayElements( env, ia, arr, 0 );
140 return;
141}
142
143/**//*
144 * Class: JavaCode
145 * Method: cReturnIntArray
146 * Signature: ()[I
147 */
148JNIEXPORT jintArray JNICALL Java_JavaCode_cReturnIntArray
149(JNIEnv *env, jobject obj) {
150 jintArray ia;
151 jint len, *arr;
152 fprintf( stderr, "--------Java_JavaCode_cReturnIntArray\n" );
153 ia = (*env)->NewIntArray( env, 5 );
154 len = (*env)->GetArrayLength( env, ia );
155 arr = (*env)->GetIntArrayElements( env, ia, NULL );
156 fprintf( stderr, "----int array length = %d\n----elem =", len );
157 int i;
158 for ( i = 0; i < len; ++i ) {
159 arr[ i ] = i+1;
160 fprintf( stderr, " %d", arr[i] );
161 }
162 fprintf( stderr, "\n" );
163 (*env)->ReleaseIntArrayElements( env, ia, arr, 0 );
164 return ia;
165}
166
167/**//*
168 * Class: JavaCode
169 * Method: cPassObject
170 * Signature: (LJavaStruct;)V
171 */
172JNIEXPORT void JNICALL Java_JavaCode_cPassObject
173(JNIEnv *env, jobject inst_obj, jobject obj) {
174 fprintf( stderr, "--------Java_JavaCode_cPassObject\n" );
175 jclass cls = (*env)->GetObjectClass( env, obj );
176 jfieldID fid_i = (*env)->GetFieldID( env, cls, "i", "I" );
177 jfieldID fid_str = (*env)->GetFieldID( env, cls, "str", "Ljava/lang/String;" );
178 jfieldID fid_ia = (*env)->GetFieldID( env, cls, "ia", "[I" );
179 jint i = (*env)->GetIntField( env, obj, fid_i );
180 fprintf( stderr, "----obj.i = %d, set obj.i = %d\n", i, i+1 );
181 (*env)->SetIntField( env, obj, fid_i, i+1 );
182 jstring jstr = (jstring)(*env)->GetObjectField( env, obj, fid_str );
183 const char *str = (*env)->GetStringUTFChars( env, jstr, NULL );
184 fprintf( stderr, "----obj.str = \"%s\"\n", str );
185 (*env)->ReleaseStringUTFChars( env, jstr, str );
186 jintArray jia = (jintArray)(*env)->GetObjectField( env, obj, fid_ia );
187 jint *arr = (*env)->GetIntArrayElements( env, jia, NULL );
188 fprintf( stderr, "----obj.ia[0] = %d\n", arr[0] );
189 (*env)->ReleaseIntArrayElements( env, jia, arr, 0 );
190 return;
191}
192
193/**//*
194 * Class: JavaCode
195 * Method: cReturnObject
196 * Signature: ()LJavaStruct;
197 */
198JNIEXPORT jobject JNICALL Java_JavaCode_cReturnObject
199(JNIEnv *env, jobject obj) {
200 fprintf( stderr, "--------\n" );
201 return NULL;
202}
203
204/**//*
205 * Class: JavaCode
206 * Method: cPassObjectArray
207 * Signature: ([LJavaStruct;)V
208 */
209JNIEXPORT void JNICALL Java_JavaCode_cPassObjectArray
210(JNIEnv *env, jobject inst_obj, jobjectArray oa) {
211 fprintf( stderr, "--------Java_JavaCode_cPassObjectArray\n" );
212 jobject obj = (*env)->GetObjectArrayElement( env, oa, 1 );
213 jclass cls = (*env)->GetObjectClass( env, obj );
214 jfieldID fid_i = (*env)->GetFieldID( env, cls, "i", "I" );
215 jfieldID fid_str = (*env)->GetFieldID( env, cls, "str", "Ljava/lang/String;" );
216 jfieldID fid_ia = (*env)->GetFieldID( env, cls, "ia", "[I" );
217 jint i = (*env)->GetIntField( env, obj, fid_i );
218 fprintf( stderr, "----objarr[1].i = %d, set objarr[1].i = %d\n", i, i+1 );
219 (*env)->SetIntField( env, obj, fid_i, i+1 );
220 jstring jstr = (jstring)(*env)->GetObjectField( env, obj, fid_str );
221 const char *str = (*env)->GetStringUTFChars( env, jstr, NULL );
222 fprintf( stderr, "----objarr[1].str = \"%s\"\n", str );
223 (*env)->ReleaseStringUTFChars( env, jstr, str );
224 jintArray jia = (jintArray)(*env)->GetObjectField( env, obj, fid_ia );
225 jint *arr = (*env)->GetIntArrayElements( env, jia, NULL );
226 fprintf( stderr, "----objarr[1].ia[0] = %d\n", arr[0] );
227 (*env)->ReleaseIntArrayElements( env, jia, arr, 0 );
228 return;
229}
230
231/**//*
232 * Class: JavaCode
233 * Method: cReturnObjectArray
234 * Signature: ()[LJavaStruct;
235 */
236JNIEXPORT jobjectArray JNICALL Java_JavaCode_cReturnObjectArray
237(JNIEnv *env, jobject obj) {
238 fprintf( stderr, "--------\n" );
239 return NULL;
240}
241
242 makefile
1
2JNI_H_PATH=/usr/lib/jvm/java-6-openjdk/include
3
4LIBCFILE=cCode.c JavaCode.h cvt_mutf8_utf32.c cvt_mutf8_utf32.h
5
6libcCode.so : $(LIBCFILE)
7 gcc $(LIBCFILE) -o $@ -shared -fPIC -I$(JNI_H_PATH)
8
9JavaCode.h : JavaCode.class
10 javah -jni JavaCode
11
12JavaCode.class : JavaCode.java
13 javac $<
14
15run :
16 java -Djava.library.path=. JavaCode
17
18