[普通]java jni调用c/c++的so动态链接库简易demo

作者(passion) 阅读(168次) 评论(0) 分类( 程序)

需求:

            工作中需要多个团队协作开发,而不同团队提供的编程语言不同,比较常见的是底层交互使用C++或c来实现任务调度,java层实现业务调度或者业务实现,正好有涉及到这方面的应用,就分享一下java使用jni调用linux中so文件的几个注意事项


编写简易的demo:

    1: java代码编写jni定义的类Hello.java

package com.jni;
public class Hello{
static{
System.load("/home/admin/lib/libHello.so");
}
public native void say();

public native String world(String str);

public static void main(String...args){
Hello hello = new Hello();
hello.say();
System.out.println("java : "+hello.world("hello"));
}
}

    2:编译Hello.java - Hello.class

        javac -d . Hello.java 

        会得到 com/jni/Hello.class

   3: 编译Hello.class 生成 com_jni_Hello.h 的头文件

          javah com.jni.Hello

    4: 编写c++/c的业务代码,引用com_jni_Hello.h 的头文件,并实现定义的方法

         c代码:  Hello.c

#include "com_jni_Hello.h"
#include "string.h"
JNIEXPORT void JNICALL Java_com_jni_Hello_say(JNIEnv *env, jobject object){
 
        printf("hello world!");
  }

JNIEXPORT jstring JNICALL Java_com_jni_Hello_world(JNIEnv *env, jobject obejct, jstring string){
          const char *wd = " world!!";
          const char *getstr = (*env)->GetStringUTFChars(env,string, 0);
          char *str;

          str=strcpy(str,wd);
          str=strcpy(str,getstr); 

         jstring out= (*env)->NewStringUTF(env,str);

          return out;
  }


         c++代码:Hello.cpp

 #include "com_jni_Hello.h"
#include "string.h"
JNIEXPORT void JNICALL Java_com_jni_Hello_say(JNIEnv *env, jobject object){
        printf("hello world!");
  }


JNIEXPORT jstring JNICALL Java_com_jni_Hello_world(JNIEnv *env, jobject obejct, jstring string){
          const char *wd = " world!!";
         const char *getstr = env->GetStringUTFChars(string,JNI_FALSE);
          char *str;
          str=strcpy(str,wd);
          str=strcpy(str,getstr);
          jstring out= env->NewStringUTF(str);
          return out;
  }

    5:编译c/c++ 代码生成动态链接库 .so文件

        c编译:  -o

        gcc -fPIC -D_REENTRANT -I/home/admin/install/jdk1.8.0_131/include -I/home/admin/install/jdk1.8.0_131/include/linux -c Hello.c

       注意:第一个 -I 是jni.h    第二个是jni_md.h

                     -so

          gcc -shared -o libHello.so Hello.o

        

        c++:编译:

            g++ Hello.cpp -fPIC  -D_REENTRANT -I/home/admin/install/jdk1.8.0_131/include -I/home/admin/install/jdk1.8.0_131/include/linux -shared -o libHello.so

    6:把so的路劲添加到LD_LIBRARY_PATH变量

   export LD_LIBRARY_PATH=/home/admin/lib

 7: 运行java程序 

    java com.jni.Hello

    8:结果

    java : hello
    hello world!

------注意

1:jna是基于jni的封装,要求执行速度而言建议使用jni,但是要求开发效率而言可以直接使用jna,直接免去编译头文件和加载c/c++加载头文件这两步;

2:所有jni定义的方法都需要加入JNIEnv变量;

3:对于c++而言,新的标准库没有了.h的概念
     对于c而言没有命名空间的概念


« 上一篇:BERT代码剖析
« 下一篇:Android 编译 opencv
在这里写下您精彩的评论
  • 微信

  • QQ

  • 支付宝

返回首页
返回首页 img
返回顶部~
返回顶部 img
';