作者: Jim Wang 公众号: 巴博萨船长

摘要:本文主要讨论,如何通过JNI实现C语言设置Java二维字符串数组并返回该字符串数组。

Abstract: This article mainly discusses how to set up a Java two-dimensional string array in C language through JNI and return the string array.

作者: Jim Wang 公众号: 巴博萨船长

第一步

Java代码,注意包名,生成头文件的时候要与自己的包名和类名相吻合。然后生成class, 使用下列命令行

1
javac com/javajni/jni/Test_2_DSA.java

代码如下:

1
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
package com.javajni.jni;

public class Test_2_DSA {
static {
System.loadLibrary("Test_2_ASD");
}
/**
* @param args
*/
private static native String[][] getStringArrays();

public static void main(String[] args)
{
System.out.println("二维数组中的数组元素如下:");
// TODO Auto-generated method stub
String array[][] = getStringArrays();
for (int i = 0; i < array.length; i++)
{ // 利用双重循环将二维数组中的元素依次输出
for (int j = 0; j < array[i].length; j++)
{
System.out.print(" " + array[i][j]);
}
System.out.println();
}
}
}

第二步

生成头文件,在com 的上一级目录里面运行下列命令行:

1
javah -d ../JNI -classpath . -jni com.javajni.jni.Test_2_DSA

生成的头文件com_javajni_jni_Test_2_DSA.h内容如下,需要将头文件jni.h放在你的项目目录里面,那么引用的时候应该用引号而不是尖括号。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/* DO NOT EDIT THIS FILE - it is machine generated */
#include "jni.h"
/* Header for class com_javajni_jni_Test_2_DSA */

#ifndef _Included_com_javajni_jni_Test_2_DSA
#define _Included_com_javajni_jni_Test_2_DSA
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_javajni_jni_Test_2_DSA
* Method: getStringArrays
* Signature: ()[[Ljava/lang/String;
*/
JNIEXPORT jobjectArray JNICALL Java_com_javajni_jni_Test_12_1DSA_getStringArrays
(JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

第三步

C语言源文件,文件内容如下

1
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
#include "com_javajni_jni_Test_2_DSA.h"

static jobjectArray make_row(JNIEnv *env, jsize count, const char* elements[])
{
/*此子程序功能为做行*/
/*得到一个新的字符串对象,通过找到Java中String的父类*/
jclass stringClass = (*env)->FindClass(env, "java/lang/String");

jobjectArray row = (*env)->NewObjectArray(env, count, stringClass, 0);

jsize i;

for (i = 0; i < count; ++i)
{
/*向每一行里面填充字符串*/
(*env)->SetObjectArrayElement(env, row, i, (*env)->NewStringUTF(env, elements[i]));
}
/*返回一个二维数组的一行,此时为一个一维的数组,因为只有一列*/
return row;
}
JNIEXPORT jobjectArray JNICALL Java_com_javajni_jni_Test_12_1DSA_getStringArrays(JNIEnv *env, jclass klass)
{
/*假定我们有两行四列的字符串数组*/
const jsize NumColumns = 4; /*设置列数*/
const jsize NumRows = 2; /*设置行数*/

/*举例第一行的字符串*/
const char* beatles[] = { "John", "Paul", "George", "Ringo" };
/*得到第一行字符串数组*/
jobjectArray jbeatles = make_row(env, NumColumns, beatles);

/*举例第二行的字符串*/
const char* turtles[] = { "Leonardo", "Raphael", "Michaelangelo", "Donatello" };
/*得到第一行字符串数组*/
jobjectArray jturtles = make_row(env, NumColumns, turtles);

/*因为我们是C语言 所以调用JNI函数的时候要加一个env的参数 放在最前面*/

jobjectArray rows = (*env)->NewObjectArray(env, NumRows, (*env)->GetObjectClass(env, jbeatles), 0);

/*向的字符串数组填入第一行字符串*/
(*env)->SetObjectArrayElement(env, rows, 0, jbeatles);
/*向的字符串数组填入第一行字符串*/
(*env)->SetObjectArrayElement(env, rows, 1, jturtles);

/*返回一个字符串数组*/
return rows;
}

因为有注释,这里我就不多解释了。

第四步

编译运行,因为本人用的是Visual Studio来生成的所以没有用到编译命令。所以在这里编译过程就不解释。如有疑问可以联系我,大家共同学习。

需要声明一下51cto博客作者zuiwuxin就是作者本人,所以不存在版权问题。以后该博客将作为个人文章的主要发布地。


版权声明:
文章首发于 Jim Wang's blog , 转载文章请务必以超链接形式标明文章出处,作者信息及本版权声明。