博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于JNI程序中引用另外一个lib
阅读量:4312 次
发布时间:2019-06-06

本文共 6052 字,大约阅读时间需要 20 分钟。

我最近在写一个j2se的程序,我用的是开源的org.amse.ys.zip包里的代码,这部分代码是在FBReaderJ里抽取的,但是其中包含了一些native的方法,需要用的zlib库,而FBReaderJ由于是运行在Android平台上的,它对应的so库肯定是无法在我的程序中使用,因此,在下载了zlib的win32运行库后,我使用 

1 javah -jni org.amse.ys.zip.DeflatingDecompressor

生成了org_amse_ys_zip_DeflatingDecompressor.h 头文件,内容如下:

1 /* DO NOT EDIT THIS FILE - it is machine generated */ 2 #include "jni.h" 3 /* Header for class org_amse_ys_zip_DeflatingDecompressor */ 4  5 #ifndef _Included_org_amse_ys_zip_DeflatingDecompressor 6 #define _Included_org_amse_ys_zip_DeflatingDecompressor 7 #ifdef __cplusplus 8 extern "C" { 9 #endif10 #undef org_amse_ys_zip_DeflatingDecompressor_IN_BUFFER_SIZE11 #define org_amse_ys_zip_DeflatingDecompressor_IN_BUFFER_SIZE 2048L12 #undef org_amse_ys_zip_DeflatingDecompressor_OUT_BUFFER_SIZE13 #define org_amse_ys_zip_DeflatingDecompressor_OUT_BUFFER_SIZE 32768L14 /*15  * Class:     org_amse_ys_zip_DeflatingDecompressor16  * Method:    startInflating17  * Signature: ()I18  */19 JNIEXPORT jint JNICALL Java_org_amse_ys_zip_DeflatingDecompressor_startInflating20   (JNIEnv *, jobject);21 22 /*23  * Class:     org_amse_ys_zip_DeflatingDecompressor24  * Method:    endInflating25  * Signature: (I)V26  */27 JNIEXPORT void JNICALL Java_org_amse_ys_zip_DeflatingDecompressor_endInflating28   (JNIEnv *, jobject, jint);29 30 /*31  * Class:     org_amse_ys_zip_DeflatingDecompressor32  * Method:    inflate33  * Signature: (I[BII[B)J34  */35 JNIEXPORT jlong JNICALL Java_org_amse_ys_zip_DeflatingDecompressor_inflate36   (JNIEnv *, jobject, jint, jbyteArray, jint, jint, jbyteArray);37 38 #ifdef __cplusplus39 }40 #endif41 #endif

建立VS2005 DLL工程,加入jni.h, jni_md.h, zlib的 zconf.h, 加入zdll.lib依赖,加入DeflatingDecompressor.cpp:

1 /* 2  * Copyright (C) 2009-2013 Geometer Plus 
3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful,10 * but WITHOUT ANY WARRANTY; without even the implied warranty of11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12 * GNU General Public License for more details.13 *14 * You should have received a copy of the GNU General Public License15 * along with this program; if not, write to the Free Software16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA17 * 02110-1301, USA.18 */19 #include
20 #include "zlib.h"21 22 #include
23 #include "jni.h"24 #include "org_amse_ys_zip_DeflatingDecompressor.h"25 26 #define SIZE 1027 28 static z_stream* ourStreams[SIZE] = { 0 };29 30 extern "C"31 JNIEXPORT jint JNICALL Java_org_amse_ys_zip_DeflatingDecompressor_startInflating(JNIEnv *env, jobject thiz) {32 int i;33 for (i = 0; i < SIZE; ++i) {34 if (ourStreams[i] == 0) {35 ourStreams[i] = new z_stream;36 memset(ourStreams[i], 0, sizeof(z_stream));37 inflateInit2(ourStreams[i], -MAX_WBITS);38 return i;39 }40 }41 return -1;42 }43 44 extern "C"45 JNIEXPORT void JNICALL Java_org_amse_ys_zip_DeflatingDecompressor_endInflating(JNIEnv *env, jobject thiz, jint inflatorId) {46 if (inflatorId >= 0 && inflatorId < SIZE) {47 inflateEnd(ourStreams[inflatorId]);48 delete ourStreams[inflatorId];49 ourStreams[inflatorId] = 0;50 }51 }52 53 // returns (endFlag << 32) + ((used inLength) << 16) + outLength54 extern "C"55 JNIEXPORT jlong JNICALL Java_org_amse_ys_zip_DeflatingDecompressor_inflate(JNIEnv *env, jobject thiz, jint inflatorId, jbyteArray in, jint inOffset, jint inLength, jbyteArray out) {56 if (inflatorId < 0 || inflatorId >= SIZE) {57 return -1;58 }59 z_stream *stream = ourStreams[inflatorId];60 if (stream == 0) {61 return -2;62 }63 64 jbyte* inStart = env->GetByteArrayElements(in, 0);65 jbyte* outStart = env->GetByteArrayElements(out, 0);66 stream->next_in = (Bytef*)inStart + inOffset;67 stream->avail_in = inLength;68 stream->next_out = (Bytef*)outStart;69 const int outLength = env->GetArrayLength(out);70 stream->avail_out = outLength;71 const int code = inflate(stream, Z_SYNC_FLUSH);72 env->ReleaseByteArrayElements(in, inStart, 0);73 env->ReleaseByteArrayElements(out, outStart, 0);74 if (code == Z_OK || code == Z_STREAM_END) {75 jlong result = ((inLength - stream->avail_in) << 16) + outLength - stream->avail_out;76 if (code == Z_STREAM_END) {77 result |= ((jlong)1) << 32;78 }79 return result;80 }81 return -1024 + code;82 }

成功编译出DeflatingDecompressor.dll文件。

然后在的j2se工程的DeflatingDecompressor.java中使用

1 static {2     System.loadLibrary("libs/DeflatingDecompressor");3 }

加载动态库,得到

1 Exception in thread "main" java.lang.UnsatisfiedLinkError: D:\Works\TextLayout\NewReaderSE\libs\DeflatingDecompressor.dll: Can't find dependent libraries2     at java.lang.ClassLoader$NativeLibrary.load(Native Method)3     at java.lang.ClassLoader.loadLibrary0(Unknown Source)4     at java.lang.ClassLoader.loadLibrary(Unknown Source)5     at java.lang.Runtime.loadLibrary0(Unknown Source)6     at java.lang.System.loadLibrary(Unknown Source)7     at org.amse.ys.zip.DeflatingDecompressor.
(DeflatingDecompressor.java:7)

使用 查看DeflatingDecompressor.dll的依赖关系,发现缺少zlib1.dll, 这时候我想起来下载的zlib发布中还有一个动态库,拷贝到System32文件夹下,再试,果然可以了。

那么这时候为什么呢?经过资料查询才知道VS编译出来的lib文件有静态和动态lib的区别,简单的说:静态lib就是把所有的代码一股脑编译进lib文件中,在使用的时候配合头文件和lib文件就可以直接用了。而动态lib则是伴随着dll生成的,其中只包含了动态加载dll的代码,通过在程序中引用它,就可以省去了显式的调用dll的繁琐。

如何判断一个lib是静态还是动态的呢?我没有找到好的办法,一般来说,静态lib的发布只有两个文件:一个头文件定义了lib中的开放接口,一个.lib文件则是实现的内容;而动态lib的文件发布包含一个头文件,一个dll文件,一个lib文件,往往还有一个def文件来列出dll中的接口。根据这个就可以判断了。

好了,这就是调用没有成功的原因,我本来已经加载的lib是一个静态lib, 其实它是一个动态lib

 

转载于:https://www.cnblogs.com/yueang/p/3156402.html

你可能感兴趣的文章
Centos安装Python3
查看>>
PHP批量插入
查看>>
laravel连接sql server 2008
查看>>
Laravel框架学习笔记之任务调度(定时任务)
查看>>
laravel 定时任务秒级执行
查看>>
浅析 Laravel 官方文档推荐的 Nginx 配置
查看>>
Swagger在Laravel项目中的使用
查看>>
Laravel 的生命周期
查看>>
CentOS Docker 安装
查看>>
Nginx
查看>>
Navicat远程连接云主机数据库
查看>>
Nginx配置文件nginx.conf中文详解(总结)
查看>>
MySQL innert join、left join、right join等理解
查看>>
sdc时序约束
查看>>
NoC片上网络
查看>>
开源SoC整理
查看>>
【2020-3-21】Mac安装Homebrew慢,解决办法
查看>>
influxdb 命令行输出时间为 yyyy-MM-dd HH:mm:ss(年月日时分秒)的方法
查看>>
已知子网掩码,确定ip地址范围
查看>>
判断时间或者数字是否连续
查看>>