C語言 JNI 呼叫JAVA Demo
專案中由於mail送信部分要求使用C實現,但缺要求使用JAVA的LOG輸出。 因此這就需要使用C語言呼叫JAVA的LOG類進行輸出。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函式。實現同樣的功能。
(這樣實現,函式清晰。功能明確)。 JAVA和C 能一一對應上。
其中要注意的是。JAVA型別到C型別的轉換。
Env中的型別為 比如。JAVA: string ENV :jstring C: char*
JAVA: int ENV: jint C: int
[@more@]1. LogJni.java JAVA的LOG輸出類
/*
* 説明 :
*/
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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Java如何呼叫C語言程式,JNI技術JavaC語言
- java呼叫c++動態庫之jni呼叫JavaC++
- Android JNI實現Java與C/C++互相呼叫,以及so庫的生成和呼叫(JNI方式呼叫美圖秀秀so)AndroidJavaC++
- C++庫封裝JNI介面——實現java呼叫c++C++封裝Java
- Android JNI開發系列之Java與C相互呼叫AndroidJava
- go語言與c語言的相互呼叫GoC語言
- 使用 Rust 語言編寫 Java JNI 實現RustJava
- C語言函式呼叫棧C語言函式
- JNI:Java程式碼呼叫原生程式碼Java
- Android Studio NDK開發-JNI呼叫Java方法AndroidJava
- C語言關於多原始檔的呼叫C語言
- Linux下跨語言呼叫C++實踐LinuxC++
- JAVA呼叫C語言下的DLL檔案JavaC語言
- c語言是如何處理函式呼叫的?C語言函式
- 組合語言-019(彙編程式與c\c++相互呼叫)組合語言C++
- Java與C語言的區別?JavaC語言
- 初學計算機語言者(C語言,C++,java,pytion,C#)計算機C語言C++JavaC#
- JNI-C
- C語言C語言
- 聊聊C語言/C++—程式和程式語言C語言C++
- 【開發語言】PHP、Java、C語言的編譯執行過程PHPJavaC語言編譯
- JNI呼叫c動態連結庫函式程式碼實踐函式
- C 語言宏 + 內聯彙編實現 MIPS 系統呼叫
- C#使用OllamaSharp呼叫Llama 3、Phi 3等大語言模型C#模型
- JNI的語法
- C語言字串C語言字串
- C語言(一)C語言
- C語言: returnC語言
- C語言 typedefC語言
- C語言與嵌入式C語言的區別C語言
- C語言學習方法,怎麼學習C語言?C語言
- C+、Java、Python選擇哪個程式語言?JavaPython
- Java、Python、JS、C語言,哪個更值得學?JavaPythonJSC語言
- Python、 JAVA這種語言比較火,是不是C語言就不行了PythonJavaC語言
- Python和Java、PHP、C、C#、C++等其他語言的對比?PythonJavaPHPC#C++
- java JNI簡介Java
- java語言屬於哪種語言Java
- go語言呼叫everything的SDK介面Go
- 1901:The C programming language !(C語言)C語言