Java 以 其 跨 平 台 的 特 性 得 到 广 泛 应 用, 其 代 码 可 以 一 次 编 译 多 处 执 行。 但 正 是 这 种 特 性 给 它 带 来 了 一 定 的 局 限 性, 一 些 与 平 台 相 关 的 功 能 就 不 能 很 好 地 支 持。 幸 运 的 是Java 提 供 了 完 备 的C 语 言 接 口, 让 我 们 可 以 利 用C 语 言 的 强 大 功 能 来 弥 补Java 的 不 足。
---- 以 下 提 供 了 在JDK 1.2、Visual C++ 6.0 环 境 下 有 关Java 调 用C 函 数 的 具 体 过 程, 以 及 一 些 数 据 类 型 的 转 换 方 法。
一、 生 成 一 个Java 类
---- 里 面 包 含 一 些native 的 函 数, 这 些 函 数 就 是 将 在C 中 要 实 现 的。 源 程 序 如 下:import Java.lang.*; public class JavaCallC { public JavaCallC () { System.loadLibrary(“JavaCallC”); //载入系统动态库 } //以下两个函数将在C语言中实现 //传入参数为string类型,返回int型 public native int StrInIntOut (string_ str); //传入参数为int类型,返回string型 public native String IntInStrOut (int_ iIndex); }---- 关 于 参 数 转 换,int 和string 是 最 常 用 的 两 种 类 型, 本 文 将 在 下 面 详 细 说 明。 其 他 类 型 与 此 相 似, 从 略。
二、 编 译Java 源 文 件, 生 成C 语 言 头 文 件
---- 编 译Javac JavaCallC.Java, 生 成JavaCallC.class; 生 成 头 文 件Javah JavaCallC, 生 成JavaCallC.h。---- 生 成 的 头 文 件 如 下:
#include < jni.h > #ifndef_Included_pwdChecker #define _Included_pwdChecker #ifdef _cplusplus extern “C”{ #endif JNIEXPORT jint JNICALL_ Java_JavaCallC_StrInIntOut (JNIEnv *,jobject,jstring); JNIEXPORT jstring JNICALL_ Java_JavaCallC_IntInStrOut (JNIEnv *,jobject,jint);---- 较 早 版 本 中 生 成 方 法 不 太 一 样, 要 分 两 步, 以 上 面 的Java 文 件 为 例, 首 先 执 行Javah JavaCallC, 生 成JavaCallC.h 文 件; 然 后 执 行Javah -stubs JavaCallC, 生 成JavaCallC.c 文 件。
三、 创 建 动 态 库
---- 首 先 创 建 一 个 空 的 动 态 连 接 库 工 程 文 件; 然 后 创 建JavaCallC.c 文 件, 并 将 其 加 入 工 程。 文 件 主 要 内 容 如 下:#include < jni.h > JNIEXPORT jint JNICALL_ Java_ JavaCallC_StrInIntOut(JNIEnv*jenv, jobject_ jobj,jstring jstr) { const char *theStr; //得到Java的string类中 //所包含的字符串指针 theStr=(*jenv)- >Get_ StringUTFChars(jenv,jstr,0); return 1234; } JNIEXPORT jstring JNICALL_ Java_JavaCallC_ IntInStrOut(JNIEnv*jenv,jobject_ jobj, jint iCount) { char cpText [] =“Java call c test”; long 1GetInt = iCount; //生成string return (*jenv)- >NewStringUTF(jenv, cpText); }---- 需 要 注 意 的 是:Java 中 的int 型 数 据 是32 位 的, 在Windows 中 要 用long 型 数 据 表 示; 关 于 方 法GetStringUTFChars 和NewStringUTF 所 涉 及 到 的 内 存 空 间 不 需 要 释 放, 使 用 完 后Java 会 释 放 它 们;C 程 序 中 不 必 包 含JavaCallC.h 文 件, 但 函 数 头 必 须 和 头 文 件 中 的 保 持 一 致; 头 文 件jni.h 保 存 在Java 系 统 目 录 下 的include 中, 把 该 目 录 和 该 目 录 下 的Win32 目 录 加 入include 路 径 列 表 中 去。
---- 编 译 完 成 后, 将 动 态 库 文 件 拷 贝 到 系 统path 指 定 的 路 径 中, 就 可 以 像 使 用 其 他Java 类 一 样 使 用 这 个JavaCallC 类 了。