关键词:
转自 https://www.cnblogs.com/xyang0917/p/4172490.html
第五步、将C/C++代码编译成本地动态库文件
动态库文件名命名规则:lib+动态库文件名+后缀(操作系统不一样,后缀名也不一样)如:
Mac OS X : libHelloWorld.jnilib
Windows :HelloWorld.dll(不需要lib前缀)
Linux/Unix:libHelloWorld.so
1> Mac OS X
- gcc -dynamiclib -o /Users/yangxin/Library/Java/Extensions/libHelloWorld.jnilib jni/HelloWorld.c -framework JavaVM -I/$JAVA_HOME/include -I/$JAVA_HOME/include/darwin
我的$JAVA_HOME目录在:/Library/Java/JavaVirtualMachines/jdk1.7.0_21.jdk/Contents/Home
参数选项说明:
-dynamiclib:表示编译成动态链接库
-o:指定动态链接库编译后生成的路径及文件名
-framework JavaVM -I:编译JNI需要用到JVM的头文件(jni.h),第一个目录是平台无关的,第二个目录是与操作系统平台相关的头文件
2> Windows(以Windows7下VS2012为例)
开始菜单-->所有程序-->Microsoft Visual Studio 2012-->打开VS2012 X64本机工具命令提示,用cl命令编译成dll动态库:
- cl -I"%JAVA_HOME%\\include" -I"%JAVA_HOME%\\include\\win32" -LD HelloWorld.c -FeHelloWorld.dll
参数选项说明:
-I : 和mac os x一样,包含编译JNI必要的头文件
-LD:标识将指定的文件编译成动态链接库
-Fe:指定编译后生成的动态链接库的路径及文件名
3> Linux/Unix
- gcc -I$JAVA_HOME/include -I$JAVA_HOME/include/linux -fPIC -shared HelloWorld.c -o libHelloWorld.so
参数说明:
-I: 包含编译JNI必要的头文件
-fPIC: 编译成与位置无关的独立代码
-shared:编译成动态库
-o: 指定编译后动态库生成的路径和文件名
第六步、运行Java程序
Java在调用native(本地)方法之前,需要先加载动态库。如果在未加载动态之前就调用native方法,会抛出找不到动态链接库文件的异常。如下所示:
- Exception in thread "main" java.lang.UnsatisfiedLinkError: com.study.jnilearn.HelloWorld.sayHello(Ljava/lang/String;)Ljava/lang/String;
- at com.study.jnilearn.HelloWorld.sayHello(Native Method)
- at com.study.jnilearn.HelloWorld.main(HelloWorld.java:9)
一般在类的静态(static)代码块中加载动态库最合适,因为在创建类的实例时,类会被ClassLoader先加载到虚拟机,随后立马调用类的static静态代码块。这时再去调用native方法就万无一失了。加载动态库的两种方式:
- System.loadLibrary("HelloWorld");
- System.load("/Users/yangxin/Desktop/libHelloWorld.jnilib");
方式1:只需要指定动态库的名字即可,不需要加lib前缀,也不要加.so、.dll和.jnilib后缀
方式2:指定动态库的绝对路径名,需要加上前缀和后缀
如果使用方式1,java会去java.library.path系统属性指定的目录下查找动态库文件,如果没有找到会抛出java.lang.UnsatisfiedLinkError异常。
- Exception in thread "main" java.lang.UnsatisfiedLinkError: no HelloWorld2 in java.library.path
- at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1860)
- at java.lang.Runtime.loadLibrary0(Runtime.java:845)
- at java.lang.System.loadLibrary(System.java:1084)
- at com.study.jnilearn.HelloWorld.<clinit>(HelloWorld.java:13)
大家从异常中可以看出来,他是在java.library.path中查找该名称对应的动态库,如果在mac下找libHelloWorld.jnilib文件,linux下找libHelloWorld.so文件,windows下找libHelloWorld.dll文件,可以通过调用System.getProperties("java.library.path")方法获取查找的目录列表,下面是我本机mac os x 系统下的查找目录:
- String libraryDirs = System.getProperties("java.library.path");
- System.out.println(libraryDirs);
- // 输出结果如下:
- /Users/yangxin/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:.
有两种方式可以让java从java.library.path找到动态链接库文件,聪明的你应该已经想到了。
方式1:将动态链接库拷贝到java.library.path目录下
方式2:给jvm添加“-Djava.library.path=动态链接库搜索目录”参数,指定系统属性java.library.path的值
java -Djava.library.path=/Users/yangxin/Desktop
Linux/Unix环境下可以通过设置LD_LIBRARY_PATH环境变量,指定库的搜索目录。
费了那么大劲,终于可以运行写好的Java程序了,结果如下:
- yangxin-MacBook-Pro:JNILearn yangxin$ java -classpath ./bin com.study.jnilearn.HelloWorld
- Java Str:yangxin
- hello yangxin
如果没有将动态库拷贝到本地库搜索目录下,执行java命令,可通过添加系统属性java.library.path来指定动态库的目录,如下所示:
- yangxin-MacBook-Pro:JNILearn yangxin$ java -Djava.library.path=/Users/yangxin/Desktop -classpath ./bin com.study.jnilearn.HelloWorld
- Java Str:yangxin
- hello yangxin
windows下编译及使用libevent
Libevent官网:http://libevent.org/windows7下编译:编译环境: windows7+VS2010(1)解压libevent到F:libeventlibevent-2.0.21-stable(2)打开Microsoftvisualstudio2010命令行工具(3)修改以下三个文件,添加宏定义:在以下3个文件开头添加“#define_... 查看详情
[转]windows下编译及使用libevent
http://www.cnblogs.com/luxiaoxun/p/3603399.html Libevent官网:http://libevent.org/windows7下编译:编译环境: windows7+VS2010(1)解压libevent到F:libeventlibevent-2.0.21-stable(2)打开Microsoftvisualstud 查看详情
在mingw环境下编译assimp
使用的assimp库的版本为4.0.1,而CMake的版本为3.8.2。配置好sourcecode和buildthebinaries的路径后,点击configure,选择【MingWMakefiles】以及【nativecompilers】选项。 先是报一堆dll找不到的问题。到mingw安装目录下搜索对应的... 查看详情
ubuntu下编译hadoop(代码片段)
Ubuntu下编译Hadoop-2.9.2系统环境系统:ubuntu-18.10-desktop-amd64maven:ApacheMaven3.6.0jdk:jdk_1.8.0_201ProtocolBuffer:portoc-2.5.0OpenSSL:OpenSSL1.1.1cmake:cmake3.12.1hadoop:hadoop-2.9.2安装所需环境#安装各种所需依赖库$sudoapt 查看详情
在vc2015下编译doom3时发现出错fatalerrorc1189:#error
错误:fatalerrorC1189:#error: TheC++StandardLibraryforbidsmacroizingkeywords.EnablewarningC4005tofindtheforbiddenmacro. 解决方法:add"_XKEYCHECK_H"inPreprocessorDefinitions属性--配置属性-c 查看详情
qnx环境下编译ffmpeg及解码mp4实践(代码片段)
...处理(3)avfilter滤镜特效处理(4)avdevice各种设备的输入输出(5)avutil工具库(6)postproc后加工(7)swresample音频采样数据格式转换(8)swscale视频像素数据格式转换二在qnx710环境编... 查看详情
c语言gcc9.1.0环境下编译报错error:‘true’undeclared(firstuseinthisfunction)(代码片段)
...上验证一个单链表是否有环的c语言demo,放到gcc9.1.0的环境下编译,发现编译报错:error:‘true’undeclared(firstuseinthisfunction)分析发现是demo里使用到的true和flase编译报错了,原来gcc9.1.0下bool关键字还未支持。深入分析... 查看详情
c语言gcc9.1.0环境下编译报错error:‘true’undeclared(firstuseinthisfunction)(代码片段)
...上验证一个单链表是否有环的c语言demo,放到gcc9.1.0的环境下编译,发现编译报错:error:‘true’undeclared(firstuseinthisfunction)分析发现是demo里使用到的true和flase编译报错了,原来gcc9.1.0下bool关键字还未支持。深入分析... 查看详情
如何在"特殊"的网络环境下编译docker
...Linux的虚拟机。宿主机使用VPN等方案使网络“正常”访问各种“服务”,虚拟机网卡使用NAT模式。在L 查看详情
windows下编译tensorflow1.3c++library及创建一个简单的tensorflowc++程序
...模型,利用freeze_graph工具输出.pb图文件,之后再线上生产环境windows平台上用C++代码直接调用预先训 查看详情
在windows环境idea下编译运行elasticsearch7.14.1(代码片段)
文章目录在Windows环境中IDEA下编译运行Elasticsearch7.14.1环境准备操作步骤获取源码方式一:直接通过`gitbash`执行`gitclone`命令方式二:通过IDEA界面化操作编译源码本地运行遇到的问题1.权限问题2.版本问题3.geoip报... 查看详情
win11环境下编译theia源码
1、安装gitbash\jdk\python\nodejs\yarn;2、安装windows下用于npm构建工具"npm×××tall--global--productionwindows-build-tools";3、屏蔽ffmpeg的构建"exportTHEIA_ELECTRON_SKIP_REPLACE_FFMPEG=1";4、在theia代码目录下执 查看详情
msys2环境下编译x265
HEVC(HighEfficiencyVideoCoding),是一种新的视频压缩标准。可以替代H.264/AVC编码,使得保持相同质量的情况下,体积减少40%左右。目前有多种实现版本,x265则是其中之一。常用网站:x265官网 http://www.x265.org/代码托管 https://bitbucket.o... 查看详情
linux下编译cef源码及交叉编译(代码片段)
Linux下编译CEFchromium源码及交叉编译官方编译文档:https://bitbucket.org/chromiumembedded/cef/wiki/MasterBuildQuickStart#markdown-header-linux-setup编译参数推荐:https://bitbucket.org/chromiumembedded/cef/wiki/AutomatedBuildSetup.md#markdown-header-linux-configuratio... 查看详情
linux下编译httpd程序
编译httpd程序使用的程序包httpd-2.4.25.tar.bz2环境Centos7一:先用tar工具解压程序包。 二:解压后在目录下可以看到程序包里的文件,我们重点关注的是Makefile.in的模板文件,还有README程序说明文件,以及INSTALL编译方法文件... 查看详情
linux下编译c++程序报错nosuchfileordirectory是啥原因?
参考技术A报错nosuchfileordirectory是因为有空格,或者是etc/profile配置文件出错导致,和.o文件没有关系这只是一个类型C++报错,具体改正方法如下:1、比如下图把文件命名为LakeCounting.cpp,编译时把他认为是两个文件,去掉中间的空... 查看详情
debian下编译安装poco
系统环境:debian版本:Linuxlocalhost.localdomain3.10.0-862.14.4.el7.x86_64#1SMPWedSep2615:12:11UTC2018x86_64x86_64x86_64GNU/Linuxpoco版本:poco-1.9.0-all.tar.gz 安装是在docker环境下新建debian环境进行的。经过多次测试,亲测成功。首先需确保机 查看详情
android之从零开始jni研发(代码片段)
...JNI手册英文版JNI手册中文版Oracleg官方JNI文档1.NDK安装以及环境配置AndroidStudio2.2及以上参考链接GettingStartedwiththeNDKMAC端手撕NDK环境搭建选择NDK版本下载NDKDownloads解压下载文件设置环境,到用户的根目录,打开.bash_profile文件... 查看详情