当前位置: 首页 > news >正文

杨浦做网站公司/网页链接

杨浦做网站公司,网页链接,做外贸网站流程,谢岗镇做网站由于要在android平台上做一个so动态链接库,所以今天抽空看了一下jni。以前只是听说过java通过jni和C/C互调,但是由于项目中没有真正用到这项技术,所以也没有抽出时间专门学习。现在正好趁这个机会系统学习一下jni。今天参考某本书&#xff0c…

由于要在android平台上做一个so动态链接库,所以今天抽空看了一下jni。以前只是听说过java通过jni和C/C++互调,但是由于项目中没有真正用到这项技术,所以也没有抽出时间专门学习。现在正好趁这个机会系统学习一下jni。今天参考某本书,做了一个小的demo(传说中的HelloWorld)。参考书是开发的windows平台中的dll动态库,而我做的是LInux平台上的so动态库。由于之前一直做java,对linux上的GNU环境不是很熟悉,遇到一些问题,也在这篇博客里做一下记录。

首先介绍一下我的开发环境:jdk1.6,Ubuntu 12.04 64bit,gcc 4.6.3


第一步:在我的家目录中创建java文件


在java文件中声明native方法,并且在类加载的时候加载so动态库。这里的java文件没有使用包名。java代码如下:

public class HelloJni{static{System.loadLibrary("hellojni");	}public static void main(String[] args){HelloJni helloJni = new HelloJni();helloJni.sayHello();}native void sayHello();
}


第二步:编译java文件,生成class文件


执行以下命令

javac HelloJni.java

可以看到当前目录下生成HelloJni.class

zhangjg@MyUbuntu:~$ ls
bin               HelloJni.class  simplegit-progit  workspace  视频  下载
examples.desktop  HelloJni.java   ticgit            公共的     图片  音乐
HelloJni.c~       HelloJni.java~  Ubuntu One        模板       文档  桌面


第三步:生成头文件


执行javah命令,生成c头文件

javah HelloJni

可以看到当前目录下出现HelloJni.h头文件。

zhangjg@MyUbuntu:~$ ls
bin               HelloJni.h        ticgit      模板  下载
examples.desktop  HelloJni.java     Ubuntu One  视频  音乐
HelloJni.c~       HelloJni.java~    workspace   图片  桌面
HelloJni.class    simplegit-progit  公共的      文档

该文件的全部内容如下:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloJni */#ifndef _Included_HelloJni
#define _Included_HelloJni
#ifdef __cplusplus
extern "C" {
#endif
/** Class:     HelloJni* Method:    sayHello* Signature: ()V*/
JNIEXPORT void JNICALL Java_HelloJni_sayHello(JNIEnv *, jobject);#ifdef __cplusplus
}
#endif
#endif

第四步:创建c文件


在当前目录下创建HelloJni.c文件,在这个c文件中包含上一步中创建的HelloJni.h头文件,并且实现头文件中声明的方法,代码如下:

#include <stdio.h>
#include "HelloJni.h"/*该方法在HelloJni.h中声明JNIEXPORT和JNICALL都是JNI中的关键字JNIEnv对应java线程中调用的JNI环境,通过这个参数可以调用一些JNI函数jobject对应当前java线程中调用本地方法的对象
*/
JNIEXPORT void JNICALL Java_HelloJni_sayHello(JNIEnv * env, jobject obj)
{printf("HelloJni! This is my first jni call.");
}



第五步:编译c文件成动态库


执行gcc命令,将c文件编译成动态库,输入以下命令

zhangjg@MyUbuntu:~$ gcc -shared -o hellojni.so HelloJni.c

得到以下错误提示

In file included from HelloJni.c:2:0:
HelloJni.h:2:17: 致命错误: jni.h:没有那个文件或目录
编译中断。

这是因为在HelloJni.h头文件中又包含了其他jni.h头文件,jni.h中又包括了jni_md.h头文件,这两个头文件在jdk的安装目录中而不在系统的头文件目录中,gcc不知道去哪里找这两个头文件,所以要在gcc的命令中指定这两个头文件所在的路径

执行以下命令:

gcc -fPIC -D_REENTRANT -I/develop/jdk1.6.0_31/include -I//develop/jdk1.6.0_31/include/linux -shared -o hellojni.so HelloJni.c

可以看到当前目录下出现了hellojni.so动态库。

zhangjg@MyUbuntu:~$ ls
bin               HelloJni.class  hellojni.so       workspace  图片  桌面
examples.desktop  HelloJni.h      simplegit-progit  公共的     文档
HelloJni.c        HelloJni.java   ticgit            模板       下载
HelloJni.c~       HelloJni.java~  Ubuntu One        视频       音乐


第六步:执行class文件,验证jni调用是否成功


执行如下命令:

java HelloJni
抛出如下错误:

Exception in thread "main" java.lang.UnsatisfiedLinkError: no hellojni in java.library.pathat java.lang.ClassLoader.loadLibrary(ClassLoader.java:1738)at java.lang.Runtime.loadLibrary0(Runtime.java:823)at java.lang.System.loadLibrary(System.java:1028)at HelloJni.<clinit>(HelloJni.java:4)
Could not find the main class: HelloJni.  Program will exit.
错误提示很明白,意思是说java虚拟机不能在java.library.path路径中找到hellojni动态库。所以,虚拟机在加载动态链接库时,并不是在当前目录下寻找,而是在 java.library.path指定的路径下寻找。而java.library.path路径到底是什么呢?可以看出这应该是虚拟机的一个属性,下面编写一段程序,打印出这个路径。代码如下:

public class TestLibraryPath{public static void main(String[] args){String path = System.getProperty("java.library.path");System.out.println(path);}
}

执行之后打印出的结果为

/develop/jdk1.6.0_31/jre/lib/amd64/server:/develop/jdk1.6.0_31/jre/lib/amd64:/develop/jdk1.6.0_31/jre/../lib/amd64:/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib

/develop/jdk1.6.0_31是我的jdk的安装目录。 java.library.path指定的共享库目录并不只有一个,而是有多个,之间用:分割。也就是说必须把共享库放到这写目录中的其中一个中,虚拟机才能加载这个动态库。我们把这个动态库放到/develop/jdk1.6.0_31/jre/lib/amd64目录中。执行如下命令:

zhangjg@MyUbuntu:~$ sudo cp hellojni.so /develop/jdk1.6.0_31/jre/lib/amd64/hellojni.so
将目录切换到 /develop/jdk1.6.0_31/jre/lib/amd64中,可以看到hellojni.so

zhangjg@MyUbuntu:~$ cd /develop/jdk1.6.0_31/jre/lib/amd64
zhangjg@MyUbuntu:/develop/jdk1.6.0_31/jre/lib/amd64$ ls | grep hellojni.so
hellojni.so
再次用java命令执行HelloJni,发现还是报相同的错误,也就是链接错误,找不到要加载的动态库。

修改目录/develop/jdk1.6.0_31/jre/lib/amd64中的hellojni.so的权限试一下

zhangjg@MyUbuntu:/develop/jdk1.6.0_31/jre/lib/amd64$ sudo chmod 777 hellojni.so
改变权限后,执行java HelloJni, 还是出现同样的错误。

这就奇怪了, 明明将动态库放入系统指定的目录中,并且增加了所有权限,为什么还是无法加载呢?经过调查得知,linux的动态库命名必须以lib开头,即libXXX.so。XXX是动态库的名字,也就是加载的时候指定名字为XXX而不是libXXX。所以只要将hellojni.so改名为libhellojni.so即可。执行以下命令更改名字:

zhangjg@MyUbuntu:/develop/jdk1.6.0_31/jre/lib/amd64$ sudo mv hellojni.so libhellojni.so

再次执行java HelloJni,打印出c函数中要输出的字符串:

zhangjg@MyUbuntu:~$ java HelloJni
HelloJni! This is my first jni call.

到此为止, Linux上的简单的jni调用示例全部完成。



http://www.jmfq.cn/news/4765069.html

相关文章:

  • 做神马网站快/seo怎么优化效果更好
  • 网站做盗版视频赚钱吗/苹果自研搜索引擎或为替代谷歌
  • 西安网站建设设计的好公司/网站收录查询网
  • 在线客户服务系统/seo怎么推广
  • 凡网站创建/巨量关键词搜索查询
  • 大兴西红门网站建设/网站seo 优化
  • 高端品牌网站建设方案/安卓内核级优化神器
  • 旅游网站设计参考文献/seo零基础教学视频
  • 睢县房产网站建设/优化防疫政策
  • 物流网站建设平台/注册一个网站
  • 网站建设的税收分类编码/网络销售平台上市公司有哪些
  • wordpress如何添加备案号代码/seo的定义
  • 成都网站建设哪家比较好/b站在线观看人数在哪
  • b2b2c o2o商城系统/优化大师班级
  • 做网站简单吗/高端大气网站建设
  • 做外贸网站诈骗/搜索引擎排名2022
  • 滨州新闻头条最新消息/南京seo推广优化
  • 有没有可以做游戏的网站/西地那非片的功能主治
  • 大型网站方案/故事式软文范例100字
  • 网页设计与网站建设+pdf/b站视频推广怎么买
  • 医疗网站建设基本流程图/肇庆seo按天收费
  • 桂林 门户网站/网络推广项目计划书
  • 类似站酷的设计类网站/互联网营销的优势
  • dnf做代练哪个网站好点/百度排行榜风云榜小说
  • 网站建设一般需要多少钱/英文谷歌seo
  • 阿里云建站方案/系统推广公司
  • 建设银行河北省分行官方网站/优化网站排名公司
  • 做网站建设公司赚钱吗/网站运营推广
  • 做网站哈尔滨/扬州seo推广
  • 怎样自己做免费网站/宣传推广方案怎么写