JNI Java调用C代码
环境 Ubuntu12.04 + openJDK6JNI中使用“修改的UTF8”编码,而Linux下wchar_t使用UTF32,注意转码。
Java代码
1
public
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![]()
157![]()
class
JavaStruct
{
158
public int i;
159
public String str;
160
public int[] ia;
161
}
162![]()
163

2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

21
22
23
24

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69

70
71
72
73
74

75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131

132
133
134

135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157

158
159
160
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
8![]()
extern
"
C
"
{
9
#endif
10![]()
/**//*
11
* Class: JavaCode
12
* Method: cVoid
13
* Signature: ()V
14
*/
15
JNIEXPORT void JNICALL Java_JavaCode_cVoid
16
(JNIEnv *, jobject);
17![]()
18![]()
/**//*
19
* Class: JavaCode
20
* Method: cVoidStatic
21
* Signature: ()V
22
*/
23
JNIEXPORT void JNICALL Java_JavaCode_cVoidStatic
24
(JNIEnv *, jclass);
25![]()
26![]()
/**//*
27
* Class: JavaCode
28
* Method: cPassRuturnInt
29
* Signature: (I)I
30
*/
31
JNIEXPORT jint JNICALL Java_JavaCode_cPassRuturnInt
32
(JNIEnv *, jobject, jint);
33![]()
34![]()
/**//*
35
* Class: JavaCode
36
* Method: cPassString
37
* Signature: (Ljava/lang/String;)V
38
*/
39
JNIEXPORT void JNICALL Java_JavaCode_cPassString
40
(JNIEnv *, jobject, jstring);
41![]()
42![]()
/**//*
43
* Class: JavaCode
44
* Method: cReturnString
45
* Signature: ()Ljava/lang/String;
46
*/
47
JNIEXPORT jstring JNICALL Java_JavaCode_cReturnString
48
(JNIEnv *, jobject);
49![]()
50![]()
/**//*
51
* Class: JavaCode
52
* Method: cPassIntArray
53
* Signature: ([I)V
54
*/
55
JNIEXPORT void JNICALL Java_JavaCode_cPassIntArray
56
(JNIEnv *, jobject, jintArray);
57![]()
58![]()
/**//*
59
* Class: JavaCode
60
* Method: cReturnIntArray
61
* Signature: ()[I
62
*/
63
JNIEXPORT jintArray JNICALL Java_JavaCode_cReturnIntArray
64
(JNIEnv *, jobject);
65![]()
66![]()
/**//*
67
* Class: JavaCode
68
* Method: cPassObject
69
* Signature: (LJavaStruct;)V
70
*/
71
JNIEXPORT void JNICALL Java_JavaCode_cPassObject
72
(JNIEnv *, jobject, jobject);
73![]()
74![]()
/**//*
75
* Class: JavaCode
76
* Method: cReturnObject
77
* Signature: ()LJavaStruct;
78
*/
79
JNIEXPORT jobject JNICALL Java_JavaCode_cReturnObject
80
(JNIEnv *, jobject);
81![]()
82![]()
/**//*
83
* Class: JavaCode
84
* Method: cPassObjectArray
85
* Signature: ([LJavaStruct;)V
86
*/
87
JNIEXPORT void JNICALL Java_JavaCode_cPassObjectArray
88
(JNIEnv *, jobject, jobjectArray);
89![]()
90![]()
/**//*
91
* Class: JavaCode
92
* Method: cReturnObjectArray
93
* Signature: ()[LJavaStruct;
94
*/
95
JNIEXPORT jobjectArray JNICALL Java_JavaCode_cReturnObjectArray
96
(JNIEnv *, jobject);
97![]()
98
#ifdef __cplusplus
99
}
100
#endif
101
#endif
102
2
3
4
5
6
7
8

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
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
*/
13
JNIEXPORT
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
*/
24
JNIEXPORT
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
*/
35
JNIEXPORT 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
*/
47
JNIEXPORT
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
*/
86
JNIEXPORT 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
*/
118
JNIEXPORT
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
*/
148
JNIEXPORT 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
*/
172
JNIEXPORT
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
*/
198
JNIEXPORT 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
*/
209
JNIEXPORT
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
*/
236
JNIEXPORT jobjectArray JNICALL Java_JavaCode_cReturnObjectArray
237![]()
(JNIEnv
*
env, jobject obj)
{
238
fprintf( stderr, "--------\n" );
239
return NULL;
240
}
241![]()
242
2
3
4
5
6
7
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22
23
24
25

26
27
28
29
30
31
32
33
34
35
36

37
38
39
40
41
42
43
44
45
46
47
48

49
50
51
52
53
54
55

56
57
58
59
60
61
62
63
64
65
66

67
68
69
70
71
72
73

74
75
76
77
78
79
80
81
82
83
84
85
86
87

88
89
90
91
92
93
94
95

96
97
98
99
100
101
102
103

104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119

120
121
122
123
124
125

126
127
128
129
130
131

132
133
134
135

136
137
138
139
140
141
142
143
144
145
146
147
148
149

150
151
152
153
154
155
156
157
158

159
160
161
162
163
164
165
166
167
168
169
170
171
172
173

174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199

200
201
202
203
204
205
206
207
208
209
210

211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237

238
239
240
241
242
makefile
1
2
JNI_H_PATH
=/
usr
/
lib
/
jvm
/
java
-
6
-
openjdk
/
include
3![]()
4
LIBCFILE
=
cCode.c JavaCode.h cvt_mutf8_utf32.c cvt_mutf8_utf32.h
5![]()
6
libcCode.so : $(LIBCFILE)
7
gcc $(LIBCFILE)
-
o $@
-
shared
-
fPIC
-
I$(JNI_H_PATH)
8![]()
9
JavaCode.h : JavaCode.
class
10
javah
-
jni JavaCode
11![]()
12
JavaCode.
class
: JavaCode.java
13
javac $
<
14![]()
15
run :
16
java
-
Djava.library.path
=
. JavaCode
17![]()
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18