来自ibm的jni教程
从 Java 程序调用 C 或 C ++ 代码的过程由六个步骤组成。我们将在下面几页中深入讨论每个步骤,但还是先让我们迅速地浏览一下它们。
编写 Java 代码。我们将从编写 Java 类开始,这些类执行三个任务:声明将要调用的本机方法;装入包含本机代码的共享库;然后调用该本机方法。
编译 Java 代码。在使用 Java 类之前,必须成功地将它们编译成字节码。
创建 C/C++ 头文件。C/C++ 头文件将声明想要调用的本机函数说明。然后,这个头文件与 C/C++ 函数实现(请参阅步骤 4)一起来创建共享库(请参阅步骤 5)。
编写 C/C++ 代码。这一步实现 C 或 C++ 源代码文件中的函数。C/C++ 源文件必须包含步骤 3 中创建的头文件。
创建共享库文件。从步骤 4 中创建的 C 源代码文件来创建共享库文件。
运行 Java 程序。运行该代码,并查看它是否有用。我们还将讨论一些用于解决常见错误的技巧。 
 
步骤 1:编写 Java 代码 第 3 页(共16 页) 
我们从编写 Java 源代码文件开始,它将声明本机方法(或方法),装入包含本机代码的共享库,然后实际调用本机方法。这里是名为 Sample1.java 的 Java 源代码文件的示例:
 1. public class Sample1
 2. {
 3.   public native int intMethod(int n);
 4.   public native boolean booleanMethod(boolean bool);
 5.   public native String stringMethod(String text);
 6.   public native int intArrayMethod(int[] intArray);
 7.
 8.   public static void main(String[] args)
 9.   {
10.     System.loadLibrary("Sample1");
11.     Sample1 sample = new Sample1();
12.     int     square = sample.intMethod(5);
13.     boolean bool   = sample.booleanMethod(true);
14.     String  text   = sample.stringMethod("JAVA");
15.     int     sum    = sample.intArrayMethod(
16.                         new int[]{1,1,2,3,5,8,13} );
17.
18.     System.out.println("intMethod: " + square);
19.     System.out.println("booleanMethod: " + bool);
20.     System.out.println("stringMethod: " + text);
21.     System.out.println("intArrayMethod: " + sum);
22.   }
23. } 第二步接下来,我们需要将 Java 代码编译成字节码。完成这一步的方法之一是使用随 SDK 一起提供的 Java 编译器 javac。用来将 Java 代码编译成字节码的命令是:    
javac Sample1.java第三步是创建 C/C++ 头文件,它定义本机函数说明。完成这一步的方法之一是使用 javah.exe,它是随 SDK 一起提供的本机方法 C 存根生成器工具。这个工具被设计成用来创建头文件,该头文件为在 Java 源代码文件中所找到的每个 native 方法定义 C 风格的函数。这里使用的命令是: 
javah Sample1 
第四步当谈到编写 C/C++ 函数实现时,有一点需要牢记:说明必须和 Sample1.h 的函数声明完全一样。我们将研究用于 C 实现和 C++ 实现的完整代码,然后讨论两者之间的差异
以下是 Sample1.c,它是用 C 编写的实现:
 1. #include "Sample1.h"
 2. #include <string.h>
 3. 
 4. JNIEXPORT jint JNICALL Java_Sample1_intMethod
 5.   (JNIEnv *env, jobject obj, jint num) {
 6.    return num * num;
 7. }
 8. 
 9. JNIEXPORT jboolean JNICALL Java_Sample1_booleanMethod
10.   (JNIEnv *env, jobject obj, jboolean boolean) {
11.   return !boolean;
12. }
13.
14. JNIEXPORT jstring JNICALL Java_Sample1_stringMethod
15.   (JNIEnv *env, jobject obj, jstring string) {
16.     const char *str = (*env)->GetStringUTFChars(env, string, 0);
17.     char cap[128];
18.     strcpy(cap, str);
19.     (*env)->ReleaseStringUTFChars(env, string, str);
20.     return (*env)->NewStringUTF(env, strupr(cap));
21. }
22. 
23. JNIEXPORT jint JNICALL Java_Sample1_intArrayMethod
24.   (JNIEnv *env, jobject obj, jintArray array) {
25.     int i, sum = 0;
26.     jsize len = (*env)->GetArrayLength(env, array);
27.     jint *body = (*env)->GetIntArrayElements(env, array, 0);
28.     for (i=0; i<len; i++)
29.     { sum += body[i];
30.     }
31.     (*env)->ReleaseIntArrayElements(env, array, body, 0);
32.     return sum;
33. }
34. 
35. void main(){} 
步骤 5:创建共享库文件 第 13 页(共16 页) 
接下来,我们创建包含本机代码的共享库文件。大多数 C 和 C++ 编译器除了可以创建机器代码可执行文件以外,也可以创建共享库文件。用来创建共享库文件的命令取决于您使用的编译器。下面是在 Windows 和 Solaris 系统上执行的命令。Windows: cl -Ic:\jdk\include -Ic:\jdk\include\win32 -LD Sample1.c -FeSample1.dll 
Solaris: cc -G -I/usr/local/jdk/include -I/user/local/jdk/include/solaris Sample1.c -o Sample1.so  
最后一步是运行 Java 程序,并确保代码正确工作。因为必须在 Java 虚拟机中执行所有 Java 代码,所以需要使用 Java 运行时环境。完成这一步的方法之一是使用 java,它是随 SDK 一起提供的 Java 解释器。所使用的命令是:    
java Sample1
当运行 Sample1.class 程序时,应该获得下列结果:
PROMPT>java Sample1
intMethod: 25
booleanMethod: false
stringMethod: JAVA
intArrayMethod: 33PROMPT>

解决方案 »

  1.   

    我按照上面作做,在步骤 5:创建共享库文件时,键入:
    cl -Id:\JBuilder8\jdk1.4\include -Id:\JBuilder8\jdk1.4\include\win32 -LD Hello.c -FeHello.dll 
    对吗?可是出现“cl不是内部或外部命令的错误”?而且在生成“Hello.c”文件时,为什么还要写函数体呢?我只是想调用dll库中的函数,具体的函数实现功能都在dll库中写好了啊。如果要写函数体,我应该怎么写?