JNIJAVA和C/C++相互调用
1、JAVA可以通过JNI调用C/C++函数
2、C/C++也可以通过JNI相关函数,来调用JAVA。并且可以访问到JAVA类中所有成员变量和成员函数。
要实现C/C++调用JAVA相关功能,则需要掌握以下知识点:
1、C/C++如何找到JAVA类
2、C/C++如何获取到JAVA变量
3、C/C++如何设置Java变量
4、C/C++如何获取到JAVA函数
3、带着这些疑问,我还是来写个简单程序。
该程序主要实现以下功能:
1、java传递两个数,让C/C++做运算。
2、C/C++将运算结果,让JAVA显示。
3、java传递两个字符串,让C/C++做连接操作
4、C/C++将运算结果,让JAVA显示。
5、C/C++获取JAVA的变量,并且修改JAVA变量值。
6、Java计算并且显示。
7、C/C++获取JAVAString对象,并且修改对象值。
8、Java将修改后的值连接并且显示。
4、jnicalleachother.java代码如下:
publicclass jnicalleachother
{
float f1;
float f2;
Stringstr1;
Stringstr2;
StringstrResult;
static
{
System.loadLibrary("jnicalleachother");
}
publicnative int AddFloat(float fFirst, float fSecond);
publicnative int AddJavaFloat();
publicnative int CatString(String fFirst, String fSecond);
publicnative int CatJavaString();
publicint PrintFloat(float fFirst, float fSecond, float fResult)
{
System.out.println("fFirst:"+ fFirst);
System.out.println("fSecond:"+ fSecond);
System.out.println("Result:"+ fResult);
return0;
}
publicint PrintString(String strFirst, String strSecond, String strResult)
{
System.out.println(strFirst);
System.out.println(strSecond);
System.out.println(strResult);
return0;
}
publicint PrintModifyFloat()
{
floatfResult = (float)0.0;
System.out.println("fFirst:"+ f1);
System.out.println("fSecond:"+ f2);
fResult= f1 + f2;
System.out.println("Result:"+ fResult);
return0;
}
publicint PrintModifyString()
{
System.out.println(str1);
System.out.println(str2);
strResult= str1 + str2;
System.out.println(strResult);
return0;
}
publicstatic void main(String[] args)
{
jnicalleachotherdata = new jnicalleachother();
data.f1= (float)100.00;
data.f2= (float)1000.00;
data.AddFloat(data.f1,data.f2);
data.str1= "Java call";
data.str2= "c/c++";
data.CatString(data.str1,data.str2);
data.AddJavaFloat();
data.CatJavaString();
}
}
5、通过javah命令生成的头文件(jnicalleachother.h)如下:
/*DO NOT EDIT THIS FILE - it is machine generated */
#include<jni.h>
/*Header for class jnicalleachother */
#ifndef_Included_jnicalleachother
#define_Included_jnicalleachother
#ifdef__cplusplus
extern"C" {
#endif
/*
*Class: jnicalleachother
*Method: AddFloat
*Signature: (FF)I
*/
JNIEXPORTjint JNICALL Java_jnicalleachother_AddFloat
(JNIEnv*, jobject, jfloat, jfloat);
/*
*Class: jnicalleachother
*Method: AddJavaFloat
*Signature: ()I
*/
JNIEXPORTjint JNICALL Java_jnicalleachother_AddJavaFloat
(JNIEnv*, jobject);
/*
*Class: jnicalleachother
*Method: CatString
*Signature: (Ljava/lang/String;Ljava/lang/String;)I
*/
JNIEXPORTjint JNICALL Java_jnicalleachother_CatString
(JNIEnv*, jobject, jstring, jstring);
/*
*Class: jnicalleachother
*Method: CatJavaString
*Signature: ()I
*/
JNIEXPORTjint JNICALL Java_jnicalleachother_CatJavaString
(JNIEnv*, jobject);
#ifdef__cplusplus
}
#endif
#endif
6、本地实现源文件(jnicalleachother.c)
#include"jnicalleachother.h"
/*
*Class: jnicalleachother
*Method: AddFloat
*Signature: (FF)I
*/
JNIEXPORTjint JNICALL Java_jnicalleachother_AddFloat(JNIEnv * pEnv, jobjectpObject, jfloat fFirst, jfloat fSecond)
{
jfloatfResult = 0.0;
jintiResult = 0;
fResult= fFirst + fSecond;
jclasscls = (* pEnv)->GetObjectClass(pEnv,pObject);
jmethodIDprintFloat = (* pEnv)->GetMethodID(pEnv,cls,"PrintFloat","(FFF)I");
iResult= (* pEnv)->CallIntMethod(pEnv, pObject,printFloat, fFirst,fSecond, fResult);
}
/*
*Class: jnicalleachother
*Method: AddJavaFloat
*Signature: ()I
*/
JNIEXPORTjint JNICALL Java_jnicalleachother_AddJavaFloat(JNIEnv * pEnv,jobject pObject)
{
jfloatfResult = 0.0;
intiResult = 0;
jclasscls= (* pEnv)->GetObjectClass(pEnv, pObject);
jfieldIDffield1 =(*pEnv)->GetFieldID(pEnv, cls,"f1","F");
(*pEnv)->SetFloatField(pEnv,pObject,ffield1,15848.00);
jfieldIDffield2 =(*pEnv)->GetFieldID(pEnv, cls,"f2","F");
(*pEnv)->SetFloatField(pEnv,pObject,ffield2,125454.00);
jmethodIDprintFloat = (* pEnv)->GetMethodID(pEnv,cls,"PrintModifyFloat","()I");
iResult= (* pEnv)->CallIntMethod(pEnv, pObject,printFloat);
}
/*
*Class: jnicalleachother
*Method: CatString
*Signature: (Ljava/lang/String;Ljava/lang/String;)I
*/
JNIEXPORTjint JNICALL Java_jnicalleachother_CatString(JNIEnv * pEnv, jobjectpObject, jstring strFirst, jstring strSecond)
{
charszResult[128] = {0};
char* pszFirst = NULL;
char* pszSecond = NULL;
intiResult = 0;
jstringstrResult = NULL;
pszFirst= (* pEnv)->GetStringUTFChars(pEnv, strFirst, NULL);
pszSecond= (* pEnv)->GetStringUTFChars(pEnv, strSecond, NULL);
strcpy(szResult,pszFirst);
strcat(szResult," ");
strcat(szResult,pszSecond);
jclasscls = (* pEnv)->GetObjectClass(pEnv,pObject);
jmethodIDprintString = (* pEnv)->GetMethodID(pEnv,cls,"PrintString","(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I");
strResult= (* pEnv)->NewStringUTF(pEnv, szResult);
iResult= (* pEnv)->CallIntMethod(pEnv, pObject,printString, strFirst,strSecond, strResult);
(*pEnv)->ReleaseStringUTFChars(pEnv, strFirst, pszFirst);
(*pEnv)->ReleaseStringUTFChars(pEnv, strSecond, pszSecond);
}
/*
*Class: jnicalleachother
*Method: CatJavaString
*Signature: ()I
*/
JNIEXPORTjint JNICALL Java_jnicalleachother_CatJavaString(JNIEnv * pEnv,jobject pObject)
{
intiResult = 0;
jstringstrFirst= (*pEnv)->NewStringUTF(pEnv, "C/C++ call ");
jstringstrSecond= (*pEnv)->NewStringUTF(pEnv, "Java");
jclasscls= (* pEnv)->GetObjectClass(pEnv, pObject);
jfieldIDffield1 =(*pEnv)->GetFieldID(pEnv,cls,"str1","Ljava/lang/String;");
(*pEnv)->SetObjectField(pEnv,pObject,ffield1,strFirst);
jfieldIDffield2 =(*pEnv)->GetFieldID(pEnv,cls,"str2","Ljava/lang/String;");
(*pEnv)->SetObjectField(pEnv,pObject,ffield2,strSecond);
jmethodIDprintString = (* pEnv)->GetMethodID(pEnv,cls,"PrintModifyString","()I");
iResult= (* pEnv)->CallIntMethod(pEnv, pObject,printString);
}
7、运行结果:
drjiang@drjiang:~/work/jni/jnicalleachother$java jnicalleachother
fFirst:100.0
fSecond:1000.0
Result:1100.0
Javacall
c/c++
Javacall c/c++
fFirst:15848.0
fSecond:125454.0
Result:141302.0
C/C++call
Java
C/C++call Java