项目中由于mail送信部分要求使用C实现

本文介绍了一种在C语言环境中调用Java LOG类输出日志的方法。通过JNI接口实现了C语言与Java之间的交互,详细展示了从启动JVM、加载类到调用具体方法的过程,并提供了一个完整的示例。

项目中由于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

 

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包的引入。

相关知识 为了完成本关任务,你需要掌握: 实体-联系图(E-R图)的概念 实体-联系图的符号表示,能够根据需求画出E-R图 实体-联系图(E-R图)的概念 实体-联系图(Entity Relationship Diagram,ERD),E-R图是进行需求分析、归纳、整理、表达和优化现实世界数据及其联系的重要工具。E-R图是用来建立数据模型的工具。数据模型是一种面向问题的数据模型,是按照用户的观点对数据建立的模型。它描述了从用户角度看到的数据,反映了用户的现实环境,而且与在软件系统中的实现方法无关。数据模型中包含3种相互关联的信息:数据对象(实体)、数据对象的属性及数据对象彼此间相互连接的关系。 数据对象(实体) 数据对象: 是对软件必须理解的复合信息的抽象。 复合信息: 是指具有一系列不同性质或属性的事物,仅有单个值的事物(例如,宽度)不是数据对象。 可以由一组属性来定义的实体都可以被认为是数据对象。如:外部实体、事物、行为、事件、角色、单位、地点或结构等。 数据对象彼此间是有关联的。 例如:在消息系统中存在多个实体,如用户、私信、邮件发送任务、邮件发送记录、系统消息等。 属性 属性定义了数据对象的性质。必须把一个或多个属性定义为“标识符”,当我们希望找到数据对象的一个实例时,用标识符属性作为“关键字”(通常简称为“键”)。 例如:在消息系统中,用户具有用户姓名、用户编号、email等属性。 联系 数据对象彼此之间相互连接的方式称为联系,也称为关系。联系可分为以下3种类型: 一对一联系(1∶1) 在消息系统中,用户与私信的联系是一对一的。例如:A用户给B用户发送一条私信,那么这条私信和B用户就是一对一的关系。 一对多联系(1∶N) 在消息系统中,邮件发送任务与邮件发送记录之间存在一对多的联系。在处理发送任务时,一个邮件发送任务可以拆解成多条邮件发送记录,而多条邮件发送记录可以由一个邮件发送任务拆解而来。 多对多联系(M∶N) 在消息系统中,系统消息与用户之间存在着多对多的联系,一条系统消息可以推送给多个用户,同时一个用户也可以被推送多条系统消息。 实体-联系图的符号 ER图中包含了实体(即数据对象)关系和属性等3种基本成分: 通常用矩形框代表实体; 用连接相关实体的菱形框表示关系; 用椭圆形或圆角矩形表示实体(或关系)的属性; 并用直线把实体(或关系)与其属性连接起来; 闯关要求 在消息系统中,用户(user)拥有用户编号(user_id),用户姓名(user_name),邮箱(user_email)等信息; 私信(private_letter)拥有私信编号(private_letter_id),已读状态(read_status),创建时间(create_time),私信内容(private_letter_content),接受者编号(receiver_id),发送者编号(sender_id),会话者编号(conversationalist_id),当前用户编号(user_id)等信息; 私信(private_letter)与用户(users)之间是通过私信发送(send)联系起来的,私信发送(send)拥有发送时间(send_time)和已读状态(read_status)两个信息。 邮件发送任务(mail_send_task)拥有发送者编号(sender_id),邮件发送任务编号(mail_send_task_id),待发送的邮件串(mail_string),邮件主题(mail_topic),邮件内容(mail_content),创建时间(create_time),处理发送任务时间(process_time),处理状态(process_status)等信息; 邮件发送记录(email_send_record)拥有邮件发送记录编号(mail_send_record_id),邮件地址(mail_address),邮件发送任务编号(mail_send_task_id),创建时间(create_time),发送时间(send_time),发送状态(send_status)等信息; 邮件发送任务(email_send_task)和邮件发送记录(email_send_record)之间是通过处理发送任务(process_send_task)联系起来的,其中处理发送任务(process_send_task)拥有处理时间(process_time)和任务状态(task_status)两个信息; 系统消息(system_message)拥有消息编号(system_message_id),发送者编号(sender_id),消息跳转链接数(message_redirection_link_count),创建时间(create_time),已读状态(read_status),消息类型(system_message_type),消息来源(system_message_source),额外信息(extra_information),消息内容(system_message_content),接收者编号(receiver_id)等信息; 系统消息(system_message)和用户(user)之间是通过推送(push)联系起来的,其中推送(push)具有推送时间(push_time)、消息状态(system_message_status)等信息。 测试说明 请按照描述画出众包模块E-R图中的需求分类的实体和属性以及权限与需求分类之间的联系。请将文件保存至“/home/headless/Desktop/workspace/myshixun/ER图/submit/step_detail_2/”目录下,文件命名为“step2.mdj”。 注意事项 案例描述中的加粗部分即是E-R图中的各种元素,请注意甄别。 使用桌面上的StarUML工具来进行作图。画E-R图的具体流程:打开软件->点击File->点击New->在界面右侧的Model Explorer中右键点击Model->点击Add Diagram->点击ERDDiagram->在界面左侧的Entity-Relationship中即可看到绘图所需的元素。 StarUML工具中的ER图的符号表示与上述描述有些差别,请注意区分。属性的添加方法:右键点击实体->点击Add->点击Column->填入属性。
06-21
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值