java与c 之jni编程小结 -凯发k8网页登录

java, c , linux c, c#.net 技术,软件架构,领域建模,it 项目管理

 

         javac jni编程小结
                               --- jack 于湖大

 1.       什么是 jni

    jnijava native interface的缩写。从java 1.1开始,jni标准成为java平台的一部分,它允许java和其他语言进行交互。jni一开始为cc 而设计的,但是它并不妨碍你使用其他语言,只要调用约定受支持就可以了。

      使用java与本地已编译的代码交互,通常会丧失平台可移植性。但是,有些情况下这样做是可以接受的,甚至是必须的,比如,使用一些旧的库,与硬件、操作系统进行交互,或者为了提高程序的性能。

   关于 jni 的用法很简单,有点像 java 里的 reflect 的工作机制,有兴趣的朋友可以参看更详细的书

2.       jni 开发步骤

l          编写带有native声明的方法的java

l          使用javac ide(jbuilder,eclipse)编译所编写的java

l          使用javah -jni java类名生成扩展名为h的头文件

l          使用c 实现本地方法,对调用签名可用 javap –s –p [类全名] 查看(开发 c 动态链接库本例是用的 vc6

注意要从 jdk下面的 include 文件夹中把 jni.h jni_md.h 两个文件 copy 到你的 vc 工程里

l          java load 动态链接库文件,调用 native 方法

3.       开发实例

1.        编写 java : (我的 ide eclipse)

/**

 * jack.wang

 */

package org.jm.jni;

import java.util.arraylist;

/**

 * @author jack.wang

 * @time mar 1, 2008

 */

public class backgroundprocess {

   static {

        system.loadlibrary("org_jm_jni_backgroundprocess");

}

// 三个 native 方法和一个 int 变量

    public native boolean checkvalid();

    public native void processdata(backgroundprocess bg);

    public native void processgarbage(string[] bg);

    public int num = 5;

    // c 中可以调用的方法

    public string backprocess(arraylist p) {

        system.out.println("这是 java 里的方法,在 c 中调用。");

        system.out.println("这个方法,是 java native checkvalid 方法调用的。");

        return "look up process ->" p;

    }

    public static void main(string[] args) {

        string[] array = new string[4];

        array[0] = "jack";

        array[1] = "maggie";

        array[2] = "rocket";

        array[3] = "tom";

        backgroundprocess bgp = new backgroundprocess();

        // 调用 c dll 中定义的方法。

        bgp.checkvalid();// 该方法回调 java 中的 backprocess 方法

        bgp.processdata(bgp);

        bgp.processgarbage(array);

        // c dll 改变了该变量

        system.out.println("number 现在的值是: " bgp.num);

    }

}

2.        生成 c 的头文件(javah 命令生成,用javap –s –p [类全名] 命令查看java 方法签名

/* do not edit this file - it is machine generated */

#include "jni.h"

/* header for class org_jm_jni_backgroundprocess */

#ifndef _included_org_jm_jni_backgroundprocess

#define _included_org_jm_jni_backgroundprocess

#ifdef __cplusplus

extern "c" {

#endif

/*

 * class:     org_jm_jni_backgroundprocess

 * method:    checkvalid

 * signature: ()z

 */

jniexport jboolean jnicall java_org_jm_jni_backgroundprocess_checkvalid

 (jnienv *, jobject);

/*

 * class:     org_jm_jni_backgroundprocess

 * method:    processdata

 * signature: (lorg/jm/jni/backgroundprocess;)v

 */

jniexport void jnicall java_org_jm_jni_backgroundprocess_processdata

 (jnienv *, jobject, jobject);

/*

 * class:     org_jm_jni_backgroundprocess

 * method:    processgarbage

 * signature: ([ljava/lang/string;)v

 */

jniexport void jnicall java_org_jm_jni_backgroundprocess_processgarbage

 (jnienv *, jobject, jobjectarray);

#ifdef __cplusplus

}

#endif

#endif

3.        开发 c dll 的原文件 (记得要加入 jni.h jni_md.h 两个文件)

发布 dll 文件, 我是配置了 path 环境变量

#include "org_jm_jni_backgroundprocess.h"

#include

#include

#include "string.h"

char* jstringtostring(jnienv* env, jstring jstr)

{

       char* rtn = null;

       jclass clsstring = env->findclass("java/lang/string");

       jstring strencode = env->newstringutf("utf-8");

       jmethodid mid = env->getmethodid(clsstring, "getbytes", "(ljava/lang/string;)[b");

       jbytearray barr= (jbytearray)env->callobjectmethod(jstr, mid, strencode);

       jsize alen = env->getarraylength(barr);

       jbyte* ba = env->getbytearrayelements(barr, jni_false);

       if (alen > 0)

       {

                 rtn = (char*)malloc(alen 1);

                 memcpy(rtn, ba, alen);

                 rtn[alen] = 0;

       }

       env->releasebytearrayelements(barr, ba, 0);

       return rtn;

}

//char* to jstring

jstring stojstring(jnienv* env, const char* pat)

{

       jclass strclass = env->findclass("ljava/lang/string;");

       jmethodid ctorid = env->getmethodid(strclass, "", "([bljava/lang/string;)v");

       jbytearray bytes = env->newbytearray(strlen(pat));

       env->setbytearrayregion(bytes, 0, strlen(pat), (jbyte*)pat);

       jstring encoding = env->newstringutf("utf-8");

       return (jstring)env->newobject(strclass, ctorid, bytes, encoding);

}

/*

* class:     org_jm_jni_backgroundprocess

* method:    checkvalid

* signature: ()z

*/

jniexport jboolean jnicall java_org_jm_jni_backgroundprocess_checkvalid

(jnienv *env, jobject obj){

jclass bgpclass=env->getobjectclass(obj);

jmethodid methodid=env->getmethodid(bgpclass,"backprocess","(ljava/util/arraylist;)ljava/lang/string;");

jobject str=env->callobjectmethod(obj,methodid,null);

jfieldid fieldid=env->getfieldid(bgpclass,"num","i");

jint number=env->getintfield(obj,fieldid);

cout << "number 值是: " <

env->setintfield(obj,fieldid,100l);

return 1;    

}

/*

* class:     org_jm_jni_backgroundprocess

* method:    processdata

* signature: (lorg/jm/jni/backgroundprocess;)v

*/

jniexport void jnicall java_org_jm_jni_backgroundprocess_processdata

(jnienv *env, jobject, jobject){

cout<< "this function do nothing " << endl;

}

/*

* class:     org_jm_jni_backgroundprocess

* method:    processgarbage

* signature: ([ljava/lang/string;)v

*/

jniexport void jnicall java_org_jm_jni_backgroundprocess_processgarbage

(jnienv *env, jobject, jobjectarray array){

jint size=env->getarraylength(array);

cout << "数组大小是: " << size << endl;

jstring tempobj=null;

    char *pszstr1 = null;

for(int i=0;i

           cout << "current value is : " << i << endl;

           tempobj=(jstring)env->getobjectarrayelement(array,i);

           const char * chars =env->getstringutfchars(tempobj, 0); 

    cout << chars << endl; 

   }

}

4.        现在你可以在 java c 之间互调了

 





本博客为学习交流用,凡未注明引用的均为本人作品,转载请注明出处,如有凯发k8网页登录的版权问题请及时通知。由于博客时间仓促,错误之处敬请谅解,有任何意见可给我留言,愿共同学习进步。
posted on 2008-03-02 08:23 jack.wang 阅读(8838) 评论(4)     所属分类: 开发技术
# re: java与c 之jni编程小结 2008-03-02 14:53
田里影院  回复  
  

# re: java与c 之jni编程小结 2008-03-03 12:29 jack.wang
有问题可以讨论  回复  
  

# re: java与c 之jni编程小结 2008-03-03 12:29 jack.wang
@xifu
什么意思  回复  
  

# re: java与c 之jni编程小结 2008-03-07 11:52 rocket
两个oo语言写出来的process式方法。。。
jack,写完你就不能用oo重构一下吗,呵呵  回复  
  

网站地图