Chinaunix首页 | 论坛 | 博客
  • 博客访问: 624812
  • 博文数量: 79
  • 博客积分: 848
  • 博客等级: 军士长
  • 技术积分: 1800
  • 用 户 组: 普通用户
  • 注册时间: 2012-06-26 19:30
文章分类

全部博文(79)

文章存档

2015年(4)

2013年(39)

2012年(36)

分类: C/C++

2013-04-27 16:54:45

hello!!骚年们好久不见,最近看代码看的实在是头大,也没什么时间写博客了,今天忙里偷闲來一发!!
首先声明本人对于大java实在所知甚少,c++学得也是马马虎虎的,这篇文章也只是简单的介绍了一下c++通过jni的方式访问java中的对象和函数的过程,所以大神可以绕过哦!
所谓jni:
JNI是Java Native Interface的缩写,中文为JAVA本地调用。从Java1.1开始,Java Native Interface(JNI)标准成为平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他语言,只要调用约定受支持就可以了。
上面所述是从度娘处粘贴过来的,不够详细的地方大家自己去百度或者google!客套话说到这里了,下面我们实现一个简单的例子!
首先我们实现一个java的类:
这个类的内容一目了然。

点击(此处)折叠或打开

  1. public class MyJni{
  2.     public String name;
  3.     public static String sayHello(String name)
  4.     {
  5.         return "Hello, " + name + "!";
  6.     }
  7.     public String sayHello(){
  8.         return "Hello, " + name + "!";
  9.     }
  10. }
然后我们将这个java文件编译成.class文件:
javac MyJni.java
然后我们可以看下该类的签名式:
javap -s -private MyJni
然后我们实现一个自己的c++文件,在其中调用jni来调用java的对象:

点击(此处)折叠或打开

  1. *************************************************************************
  2.     > File Name: MyJni.cpp
  3.     > Author: dongdaoxiang
  4.     > Func: C++ JNI
  5.     > Mail: dongdaoxiang@ncic.ac.cn
  6.     > Created Time: 2013年04月27日 星期六 13时54分34秒
  7.  ************************************************************************/
  8. #include<jni.h>
  9. #include<cstring>
  10. #include<iostream>
  11. #include<stdio.h>
  12. using namespace std;

  13. int main()
  14. {
  15.     JavaVMOption options[1];
  16.     JNIEnv *env;
  17.     JavaVM *jvm;
  18.     JavaVMInitArgs vm_args;

  19.     long status;
  20.     jclass cls;
  21.     jmethodID mid;
  22.     jfieldID fid;
  23.     jobject obj;

  24.     options[0].optionString = "-Djava.class.path=.";
  25.     memset(&vm_args, 0, sizeof(vm_args));
  26.     vm_args.version = JNI_VERSION_1_6;
  27.     vm_args.nOptions = 1;
  28.     vm_args.options = options;

  29.     status = JNI_CreateJavaVM(&jvm, (void **)&env, &vm_args);
  30.     if(status != JNI_ERR)
  31.     {
  32.         cls = env->FindClass ("MyJni");
  33.         if(cls != 0)
  34.         {
  35.             mid = env->GetStaticMethodID(cls, "sayHello", "(Ljava/lang/String;)Ljava/lang/String;");
  36.             if(mid != 0)
  37.             {
  38.                 const char *name = "world";
  39.                 jstring arg = env->NewStringUTF(name);
  40.                 jstring result = (jstring)env->CallStaticObjectMethod(cls, mid, arg);
  41.                 const char* str = env->GetStringUTFChars(result, 0);
  42.                 cout << "Result of the say hello is: " << str << endl;
  43.                 env->ReleaseStringUTFChars(result, 0);
  44.             }

  45.             mid = env->GetMethodID(cls, "", "()V");
  46.             obj = env->NewObject(cls, mid);
  47.             if (obj == 0)
  48.                {
  49.                printf("Create object failed!\n");
  50.             }
  51.             // 获取属性ID, 通过属性名和签名
  52.             fid = env->GetFieldID(cls, "name", "Ljava/lang/String;");
  53.             if (fid != 0)
  54.             {
  55.                 const char* name = "icejoywoo";
  56.                 jstring arg = env->NewStringUTF(name);
  57.                 env->SetObjectField(obj, fid, arg); // 修改属性
  58.             }
  59.              
  60.             // 调用成员方法
  61.             mid = env->GetMethodID(cls, "sayHello", "()Ljava/lang/String;");
  62.             if (mid != 0)
  63.             {
  64.                 jstring result = (jstring)env->CallObjectMethod(obj, mid);
  65.                 const char* str = env->GetStringUTFChars(result, 0);
  66.                 printf("Result of sayHello: %s\n", str);
  67.                 env->ReleaseStringUTFChars(result, 0);
  68.             }
  69.         }
  70.          
  71.         jvm->DestroyJavaVM();
  72.         return 0;
  73.     }
  74.     else
  75.     {
  76.         printf("JVM Created failed!\n");
  77.         return -1;
  78.     }
  79. }
关于上面这个jni中函数的说明大家可以翻阅jni的手册或者网上进行搜索,下面我们来说下如何搭建这个编译环境:
环境概况:
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!!经过上面的步骤我们将将本地的编译环境部署妥当了,下面开始编译:

点击(此处)折叠或打开

  1. mini@mini-ThinkPad-T420:~/unixtest$ g++ MyJni.cpp -ljvm
执行之后结果如下:

点击(此处)折叠或打开

  1. mini@mini-ThinkPad-T420:~/unixtest$ ./a.out
  2. Result of the say hello is: Hello,
  3. Result of sayHello: Hello,
OK!!

阅读(1914) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~