首先声明本人对于大java实在所知甚少,c++学得也是马马虎虎的,这篇文章也只是简单的介绍了一下c++通过jni的方式访问java中的对象和函数的过程,所以大神可以绕过哦!
所谓jni:
JNI是Java Native Interface的缩写,中文为JAVA本地调用。从Java1.1开始,Java Native Interface(JNI)标准成为平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他语言,只要调用约定受支持就可以了。
上面所述是从度娘处粘贴过来的,不够详细的地方大家自己去百度或者google!客套话说到这里了,下面我们实现一个简单的例子!
首先我们实现一个java的类:
这个类的内容一目了然。
点击(此处)折叠或打开
-
public class MyJni{
-
public String name;
-
public static String sayHello(String name)
-
{
-
return "Hello, " + name + "!";
-
}
-
public String sayHello(){
-
return "Hello, " + name + "!";
-
}
- }
javac MyJni.java
然后我们可以看下该类的签名式:
javap -s -private MyJni
然后我们实现一个自己的c++文件,在其中调用jni来调用java的对象:
点击(此处)折叠或打开
-
*************************************************************************
-
> File Name: MyJni.cpp
-
> Author: dongdaoxiang
-
> Func: C++ JNI
-
> Mail: dongdaoxiang@ncic.ac.cn
-
> Created Time: 2013年04月27日 星期六 13时54分34秒
-
************************************************************************/
-
#include<jni.h>
-
#include<cstring>
-
#include<iostream>
-
#include<stdio.h>
-
using namespace std;
-
-
int main()
-
{
-
JavaVMOption options[1];
-
JNIEnv *env;
-
JavaVM *jvm;
-
JavaVMInitArgs vm_args;
-
-
long status;
-
jclass cls;
-
jmethodID mid;
-
jfieldID fid;
-
jobject obj;
-
-
options[0].optionString = "-Djava.class.path=.";
-
memset(&vm_args, 0, sizeof(vm_args));
-
vm_args.version = JNI_VERSION_1_6;
-
vm_args.nOptions = 1;
-
vm_args.options = options;
-
-
status = JNI_CreateJavaVM(&jvm, (void **)&env, &vm_args);
-
if(status != JNI_ERR)
-
{
-
cls = env->FindClass ("MyJni");
-
if(cls != 0)
-
{
-
mid = env->GetStaticMethodID(cls, "sayHello", "(Ljava/lang/String;)Ljava/lang/String;");
-
if(mid != 0)
-
{
-
const char *name = "world";
-
jstring arg = env->NewStringUTF(name);
-
jstring result = (jstring)env->CallStaticObjectMethod(cls, mid, arg);
-
const char* str = env->GetStringUTFChars(result, 0);
-
cout << "Result of the say hello is: " << str << endl;
-
env->ReleaseStringUTFChars(result, 0);
-
}
-
-
mid = env->GetMethodID(cls, "
" , "()V");
-
obj = env->NewObject(cls, mid);
-
if (obj == 0)
-
{
-
printf("Create object failed!\n");
-
}
-
// 获取属性ID, 通过属性名和签名
-
fid = env->GetFieldID(cls, "name", "Ljava/lang/String;");
-
if (fid != 0)
-
{
-
const char* name = "icejoywoo";
-
jstring arg = env->NewStringUTF(name);
-
env->SetObjectField(obj, fid, arg); // 修改属性
-
}
-
-
// 调用成员方法
-
mid = env->GetMethodID(cls, "sayHello", "()Ljava/lang/String;");
-
if (mid != 0)
-
{
-
jstring result = (jstring)env->CallObjectMethod(obj, mid);
-
const char* str = env->GetStringUTFChars(result, 0);
-
printf("Result of sayHello: %s\n", str);
-
env->ReleaseStringUTFChars(result, 0);
-
}
-
}
-
-
jvm->DestroyJavaVM();
-
return 0;
-
}
-
else
-
{
-
printf("JVM Created failed!\n");
-
return -1;
-
}
- }
环境概况:
1、ubuntu 12.04
2、openjdk6
3、gcc 4.6.3
为了简化我们的操作我们要将/usr/lib/jvm/java-6-openjdk-i386/include路径下的两个文件:jni.h, jni_md.h拷贝到/usr/include路径下!
然后建立/usr/lib/jvm/java-6-openjdk-i386/jre/lib/i386/server/libjvm.so文件的软链接到/usr/lib/libjvm.so
sudo ln -s /usr/lib/jvm/java-6-openjdk-i386/jre/lib/i386/server/libjvm.so /usr/lib/libjvm.so
OK!!经过上面的步骤我们将将本地的编译环境部署妥当了,下面开始编译:
点击(此处)折叠或打开
- mini@mini-ThinkPad-T420:~/unixtest$ g++ MyJni.cpp -ljvm
点击(此处)折叠或打开
-
mini@mini-ThinkPad-T420:~/unixtest$ ./a.out
-
Result of the say hello is: Hello,
- Result of sayHello: Hello,