C語言 JNI 呼叫JAVA Demo

yunchat發表於2006-03-04

專案中由於mail送信部分要求使用C實現,但缺要求使用JAVALOG輸出。 因此這就需要使用C語言呼叫JAVALOG類進行輸出。C語言如何呼叫JAVA,這就使用到了JAVA提供的JNI介面。檢視了很多資料,發現都是JAVA呼叫C的例項較多,而C呼叫JAVA卻使用很少,終於在官方網檢視了些資料,

發現其實對於介面的使用還得求助於官網, 可惜那些都是英文,要是英文能好點,就不能看那麼累了。痛苦啊。

作成了Demo。包含

JAVA透過JNI呼叫C,以及C透過JNII呼叫JAVA

以下是C透過JNI呼叫JAVA 使用者LOG輸出。

JAVA呼叫C

無非如下步驟:

1.啟動JVM,載入相應的class

2.取得包含該CLASS env 環境。

3 分別取得對應於JAVA中的method ID.

4 實現對應於JAVA中的metho 將每個類的方法,都作成相應的C函式。實現同樣的功能。

(這樣實現,函式清晰。功能明確) JAVAC 能一一對應上。

其中要注意的是。JAVA型別到C型別的轉換。

Env中的型別為 比如。JAVA: string ENV :jstring C: char*

JAVA: int ENV: jint C: int

[@more@]

1 LogJni.java JAVALOG輸出類

/*

* 説明  :

*/

import java.util.*;

/**

* LogJni

*

* @version $Revision:.*$Date:$.*

*/

public class LogJni {

public LogJni() {

}

/**

* 送信?

* @param obj ?用源?(=this)

* @param iintLoginId 利用者ID

* @param istrSecondUserName ??先名

* @param gamenID 畫面功能ID

* @param excCnt ?理件數

* @param message Message

*/

public void startMail (Object obj, int iintLoginId, String istrSecondUserName, String gamenID,int excCnt, String message) {

System.out.println("startMail-Date:"+ new Date() + "LoginUser:" + iintLoginId

+ "--" + istrSecondUserName

+ " gamenID:" + gamenID

+ " excCnt: " + excCnt

+ " message:" + message);

}

/**

* 送信?

* @param obj ?用源?(=this)

* @param iintLoginId 利用者ID

* @param istrSecondUserName ??先名

* @param gamenID 畫面功能IDshi

* @param excCnt ?理件數

* @param message Message

*/

public void endMail (Object obj, int iintLoginId, String istrSecondUserName, String gamenID,int excCnt, String message) {

System.out.println("endMail-Date:"+ new Date() + "LoginUser:" + iintLoginId

+ "--" + istrSecondUserName

+ " gamenID:" + gamenID

+ " excCnt: " + excCnt

+ " message:" + message);

}

/**

* DB???

* @param obj ?用源?(=this)

* @param iintLoginId 利用者ID

* @param istrSecondUserName ??先名

* @param gamenID 畫面功能ID

* @param SQL ?SQL

* @param message Message

*/

public void startDBAccess(Object obj, int iintLoginId, String istrSecondUserName, String gamenID, String SQL, String message) {

System.out.println("startDBAccess-Date:"+ new Date() + "LoginUser:" + iintLoginId

+ "--" + istrSecondUserName

+ " gamenID:" + gamenID

+ " SQL: " + SQL

+ " message:" + message);

}

/**

* DB???

* @param obj ?用源?(=this)

* @param iintLoginId 利用者ID

* @param istrSecondUserName ??先名

* @param gamenID 畫面功能ID

* @param SQL ?SQL

* @param message Message

*/

public void endDBAccess(Object obj, int iintLoginId, String istrSecondUserName, String gamenID, String SQL, String message) {

System.out.println("endDBAccess-Date:"+ new Date() + "LoginUser:" + iintLoginId

+ "--" + istrSecondUserName

+ " gamenID:" + gamenID

+ " SQL: " + SQL

+ " message:" + message);

}

/**

*

* @param loginID 利用者ID

* @param gamenID 畫面功能ID

* @param errorMessage Error?

* @param message Message

*/

public void logError(String loginID, String gamenID, String errorMessage, String message) {

System.out.println("Error- Date:"+ new Date() + "loginID:" + loginID + "gamenID:" + gamenID + " errorMessage:" + errorMessage + "message:" + message);

}

/**

*

* @param loginID 利用者ID

* @param gamenID 畫面功能ID

* @param message Message

*/

public void logStartApplication(String loginID, String gamenID, String message) {

System.out.println("logStartApplication-Date:"+ new Date() + " loginID:" + loginID + " gamenID:" + gamenID + " message:" + message);

}

/**

*

* @param loginID 利用者ID

* @param gamenID 畫面功能ID

* @param message Message

*/

public void logEndApplication(String loginID, String gamenID, String message) {

System.out.println("logEndApplication-Date:"+ new Date() + " loginID:" + loginID + " gamenID:" + gamenID + " message:" + message);

}

/**

* 送信?

* @param obj ?用源?(=this)

* @param iintLoginId 利用者ID

* @param istrSecondUserName ??先名

* @param gamenID 畫面功能ID

* @param mail Mail資料

* @param message Message

*/

public void mail (Object obj, int iintLoginId, String istrSecondUserName, String gamenID, String mail, String message) {

System.out.println("mail-Date:"+ new Date() + "LoginUser:" + iintLoginId

+ "--" + istrSecondUserName

+ " gamenID:" + gamenID

+ " mail: " + mail

+ " message:" + message);

}

}

2 java_jvm.h (啟動JVM的。C標頭檔案)

#ifndef JAVA_JVM_H_

#define JAVA_JVM_H_

#include

#include

#define PATH_SEPARATOR ';' /* define it to be ':' on Solaris */

#define USER_CLASSPATH "." /* װصCLASS·��*/

JavaVM *jvm; /* Pointer to a Java VM */

JNIEnv *env; /* Pointer to native method interface */

void envError();

int JvmCreate() {

jint res;

#ifdef JNI_VERSION_1_2

JavaVMInitArgs vm_args;

JavaVMOption options[2];

options[0].optionString ="-Djava.class.path=" USER_CLASSPATH;

options[1].optionString = "-verbose:jni";

vm_args.version = JNI_VERSION_1_2;

vm_args.options = options;

vm_args.nOptions = 1;

vm_args.ignoreUnrecognized = JNI_TRUE;

/* Create the Java VM */

res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);

#else

JDK1_1InitArgs vm_args;

char classpath[1024];

vm_args.version = 0x00010001;

JNI_GetDefaultJavaVMInitArgs(&vm_args);

/* Append USER_CLASSPATH to the default system class path */

sprintf(classpath, "%s%c%s",

vm_args.classpath, PATH_SEPARATOR, USER_CLASSPATH);

vm_args.classpath = classpath;

/* Create the Java VM */

res = JNI_CreateJavaVM(&jvm, &env, &vm_args);

#endif /* JNI_VERSION_1_2 */

if (res < 0) {

fprintf(stderr, "Can't create Java VMn");

exit(1);

}

return 1;

}

void envError() {

if ((*env)->ExceptionOccurred(env)) {

(*env)->ExceptionDescribe(env);

}

}

void destoryJvm () {

(*jvm)->DestroyJavaVM(jvm);

}

#endif /*JAVA_JVM_H_*/

3 logjni.h 對應於 LogJni類的,C函式標頭檔案。每個函式都對應於類中的一個方法實現。

#ifndef LOGJNI_H_

#define LOGJNI_H_

#include "./java_jvm.h"

jclass logcls; /* logClass */

jmethodID startMailId;

jmethodID endMailId;

jmethodID startDBAccessId;

jmethodID endDBAccessId;

jmethodID logErrorId;

jmethodID logStartApplicationId;

jmethodID logEndApplicationId;

jmethodID mailId;

void initClass() {

logcls = (*env)->FindClass(env, "LogJni");

if (logcls == 0) {

envError();

}

}

void initMethod() {

startMailId = (*env)->GetMethodID(env, logcls, "startMail", "(Ljava/lang/Object;ILjava/lang/String;Ljava/lang/String;ILjava/lang/String;)V");

if (startMailId == 0) {

envError();

}

endMailId = (*env)->GetMethodID(env, logcls, "endMail", "(Ljava/lang/Object;ILjava/lang/String;Ljava/lang/String;ILjava/lang/String;)V");

if (endMailId == 0) {

envError();

}

startDBAccessId = (*env)->GetMethodID(env, logcls, "startDBAccess", "(Ljava/lang/Object;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");

if (startDBAccessId == 0) {

envError();

}

endDBAccessId = (*env)->GetMethodID(env, logcls, "endDBAccess", "(Ljava/lang/Object;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");

if (endDBAccessId == 0) {

envError();

}

logErrorId = (*env)->GetMethodID(env, logcls, "logError", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");

if (logErrorId == 0) {

envError();

}

logStartApplicationId = (*env)->GetMethodID(env, logcls, "logStartApplication", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");

if (logStartApplicationId == 0) {

envError();

}

logEndApplicationId = (*env)->GetMethodID(env, logcls, "logEndApplication", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");

if (logEndApplicationId == 0) {

envError();

}

mailId = (*env)->GetMethodID(env, logcls, "mail", "(Ljava/lang/Object;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");

if (mailId == 0) {

envError();

}

}

void logStartApplication(char *loginID, char *gamenID, char *message) {

jstring jstrLoginID;

jstring jstrGamenID;

jstring jstrMessage;

jstrLoginID = (*env)->NewStringUTF(env, loginID);

jstrGamenID = (*env)->NewStringUTF(env, gamenID);

jstrMessage = (*env)->NewStringUTF(env, message);

if (jstrLoginID == 0 || jstrGamenID == 0 || jstrMessage == 0) {

envError();

}

(*env)->CallStaticVoidMethod(env, logcls, logStartApplicationId, jstrLoginID, jstrGamenID, jstrMessage);

}

void logEndApplication(char *loginID, char *gamenID, char *message) {

jstring jstrLoginID;

jstring jstrGamenID;

jstring jstrMessage;

jstrLoginID = (*env)->NewStringUTF(env, loginID);

jstrGamenID = (*env)->NewStringUTF(env, gamenID);

jstrMessage = (*env)->NewStringUTF(env, message);

if (jstrLoginID == 0 || jstrGamenID == 0 || jstrMessage == 0) {

envError();

}

(*env)->CallStaticVoidMethod(env, logcls, logEndApplicationId, jstrLoginID, jstrGamenID, jstrMessage);

}

void logError(char *loginID, char *gamenID, char *errorMessage, char *message) {

jstring jstrLoginID;

jstring jstrGamenID;

jstring jstErrorMessage;

jstring jstrMessage;

jstrLoginID = (*env)->NewStringUTF(env, loginID);

jstrGamenID = (*env)->NewStringUTF(env, gamenID);

jstErrorMessage = (*env)->NewStringUTF(env, errorMessage);

jstrMessage = (*env)->NewStringUTF(env, message);

if (jstrLoginID == 0 || jstrGamenID == 0 || jstErrorMessage == 0 || jstrMessage == 0) {

envError();

}

(*env)->CallStaticVoidMethod(env, logcls, logErrorId, jstrLoginID, jstrGamenID, jstErrorMessage, jstrMessage);

}

void startMail(jobject obj, int loginId, char *secUsrName, char *gamenID, int excCnt, char *message) {

jstring jstrGamenID;

jstring jstrMessage;

jstring jstrSecUsrName;

jstrGamenID = (*env)->NewStringUTF(env, gamenID);

jstrMessage = (*env)->NewStringUTF(env, message);

jstrSecUsrName = (*env)->NewStringUTF(env, secUsrName);

if (jstrGamenID == 0 || jstrMessage == 0 || jstrSecUsrName == 0) {

envError();

}

(*env)->CallStaticVoidMethod(env, logcls, startMailId, obj, loginId, jstrSecUsrName, jstrGamenID, excCnt, jstrMessage);

}

void endMail(jobject obj, int loginId, char *secUsrName, char *gamenID, int excCnt, char *message) {

jstring jstrGamenID;

jstring jstrMessage;

jstring jstrSecUsrName;

jstrGamenID = (*env)->NewStringUTF(env, gamenID);

jstrMessage = (*env)->NewStringUTF(env, message);

jstrSecUsrName = (*env)->NewStringUTF(env, secUsrName);

if (jstrGamenID == 0 || jstrMessage == 0 || jstrSecUsrName == 0) {

envError();

}

(*env)->CallStaticVoidMethod(env, logcls, endMailId, obj, loginId, jstrSecUsrName,jstrGamenID, excCnt, jstrMessage);

}

void startDBAccess(jobject obj, int loginId, char *secUsrName, char *gamenID, char *sql, char *message) {

jstring jstrGamenID;

jstring jstrMessage;

jstring jstrSecUsrName;

jstring jstrSql;

jstrGamenID = (*env)->NewStringUTF(env, gamenID);

jstrMessage = (*env)->NewStringUTF(env, message);

jstrSecUsrName = (*env)->NewStringUTF(env, secUsrName);

jstrSql = (*env)->NewStringUTF(env, sql);

if (jstrGamenID == 0 || jstrMessage == 0 || jstrSecUsrName == 0 || jstrSql == 0) {

envError();

}

(*env)->CallStaticVoidMethod(env, logcls, startDBAccessId, obj, loginId, jstrSecUsrName,jstrGamenID, jstrSql, jstrMessage);

}

void endDBAccess(jobject obj, int loginId, char *secUsrName, char *gamenID, char *sql, char *message) {

jstring jstrGamenID;

jstring jstrMessage;

jstring jstrSecUsrName;

jstring jstrSql;

jstrGamenID = (*env)->NewStringUTF(env, gamenID);

jstrMessage = (*env)->NewStringUTF(env, message);

jstrSecUsrName = (*env)->NewStringUTF(env, secUsrName);

jstrSql = (*env)->NewStringUTF(env, sql);

if (jstrGamenID == 0 || jstrMessage == 0 || jstrSecUsrName == 0 || jstrSql == 0) {

envError();

}

(*env)->CallStaticVoidMethod(env, logcls, endDBAccessId, obj, loginId, jstrSecUsrName,jstrGamenID, jstrSql, jstrMessage);

}

void mail(jobject obj, int loginId, char *secUsrName, char *gamenID, char *mail, char *message) {

jstring jstrGamenID;

jstring jstrMessage;

jstring jstrSecUsrName;

jstring jstrMail;

jstrGamenID = (*env)->NewStringUTF(env, gamenID);

jstrMessage = (*env)->NewStringUTF(env, message);

jstrSecUsrName = (*env)->NewStringUTF(env, secUsrName);

jstrMail = (*env)->NewStringUTF(env, mail);

if (jstrGamenID == 0 || jstrMessage == 0 || jstrSecUsrName == 0 || jstrMail == 0) {

envError();

}

(*env)->CallStaticVoidMethod(env, logcls, mailId, obj, loginId, jstrSecUsrName,jstrGamenID, jstrMail, jstrMessage);

}

void initLogJni() {

JvmCreate();

initClass();

initMethod();

printf("the logjni.h initted the method of LogJni.classn");

}

#endif /*LOGJNI_H_*/

4 testjvm.c 測試demo的實現,檢查輸出。

#include

#include

#include "./logjni.h"

int main() {

initLogJni();

logStartApplication("1000", "00001", "start app");

logEndApplication("1000", "00001", "end app");

logError("1000", "00001", "error messages ", "logError");

startMail(NULL, 2000, "yunchat", "1000", 2, "startMail");

endMail(NULL, 1001, "yunchat", "1000", 2, "endMail");

startDBAccess(NULL, 1001, "yunchat", "1000", "select * from", "startDBAccess");

endDBAccess(NULL, 1001, "yunchat", "1000", "select * from", "endDBAccess");

mail(NULL, 1001, "yunchat", "1000", "error mail message", "mail");

destoryJvm();

return 0;

}

Makefile 我就不敘述了。 一定要注意。Jvm lib包的引入。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/118026/viewspace-818306/,如需轉載,請註明出處,否則將追究法律責任。

相關文章