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

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

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

 /* DO NOT EDIT THIS FILE - it is machine generated */
#include "jni.h"
/* Header for class org_amse_ys_zip_DeflatingDecompressor */ #ifndef _Included_org_amse_ys_zip_DeflatingDecompressor
#define _Included_org_amse_ys_zip_DeflatingDecompressor
#ifdef __cplusplus
extern "C" {
#endif
#undef org_amse_ys_zip_DeflatingDecompressor_IN_BUFFER_SIZE
#define org_amse_ys_zip_DeflatingDecompressor_IN_BUFFER_SIZE 2048L
#undef org_amse_ys_zip_DeflatingDecompressor_OUT_BUFFER_SIZE
#define org_amse_ys_zip_DeflatingDecompressor_OUT_BUFFER_SIZE 32768L
/*
* Class: org_amse_ys_zip_DeflatingDecompressor
* Method: startInflating
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_org_amse_ys_zip_DeflatingDecompressor_startInflating
(JNIEnv *, jobject); /*
* Class: org_amse_ys_zip_DeflatingDecompressor
* Method: endInflating
* Signature: (I)V
*/
JNIEXPORT void JNICALL Java_org_amse_ys_zip_DeflatingDecompressor_endInflating
(JNIEnv *, jobject, jint); /*
* Class: org_amse_ys_zip_DeflatingDecompressor
* Method: inflate
* Signature: (I[BII[B)J
*/
JNIEXPORT jlong JNICALL Java_org_amse_ys_zip_DeflatingDecompressor_inflate
(JNIEnv *, jobject, jint, jbyteArray, jint, jint, jbyteArray); #ifdef __cplusplus
}
#endif
#endif

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

 /*
* Copyright (C) 2009-2013 Geometer Plus <contact@geometerplus.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include <string.h>
#include "zlib.h" #include <new>
#include "jni.h"
#include "org_amse_ys_zip_DeflatingDecompressor.h" #define SIZE 10 static z_stream* ourStreams[SIZE] = { }; extern "C"
JNIEXPORT jint JNICALL Java_org_amse_ys_zip_DeflatingDecompressor_startInflating(JNIEnv *env, jobject thiz) {
int i;
for (i = ; i < SIZE; ++i) {
if (ourStreams[i] == ) {
ourStreams[i] = new z_stream;
memset(ourStreams[i], , sizeof(z_stream));
inflateInit2(ourStreams[i], -MAX_WBITS);
return i;
}
}
return -;
} extern "C"
JNIEXPORT void JNICALL Java_org_amse_ys_zip_DeflatingDecompressor_endInflating(JNIEnv *env, jobject thiz, jint inflatorId) {
if (inflatorId >= && inflatorId < SIZE) {
inflateEnd(ourStreams[inflatorId]);
delete ourStreams[inflatorId];
ourStreams[inflatorId] = ;
}
} // returns (endFlag << 32) + ((used inLength) << 16) + outLength
extern "C"
JNIEXPORT jlong JNICALL Java_org_amse_ys_zip_DeflatingDecompressor_inflate(JNIEnv *env, jobject thiz, jint inflatorId, jbyteArray in, jint inOffset, jint inLength, jbyteArray out) {
if (inflatorId < || inflatorId >= SIZE) {
return -;
}
z_stream *stream = ourStreams[inflatorId];
if (stream == ) {
return -;
} jbyte* inStart = env->GetByteArrayElements(in, );
jbyte* outStart = env->GetByteArrayElements(out, );
stream->next_in = (Bytef*)inStart + inOffset;
stream->avail_in = inLength;
stream->next_out = (Bytef*)outStart;
const int outLength = env->GetArrayLength(out);
stream->avail_out = outLength;
const int code = inflate(stream, Z_SYNC_FLUSH);
env->ReleaseByteArrayElements(in, inStart, );
env->ReleaseByteArrayElements(out, outStart, );
if (code == Z_OK || code == Z_STREAM_END) {
jlong result = ((inLength - stream->avail_in) << ) + outLength - stream->avail_out;
if (code == Z_STREAM_END) {
result |= ((jlong)) << ;
}
return result;
}
return - + code;
}

成功编译出DeflatingDecompressor.dll文件。

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

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

加载动态库,得到

 Exception in thread "main" java.lang.UnsatisfiedLinkError: D:\Works\TextLayout\NewReaderSE\libs\DeflatingDecompressor.dll: Can't find dependent libraries
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(Unknown Source)
at java.lang.ClassLoader.loadLibrary(Unknown Source)
at java.lang.Runtime.loadLibrary0(Unknown Source)
at java.lang.System.loadLibrary(Unknown Source)
at org.amse.ys.zip.DeflatingDecompressor.<clinit>(DeflatingDecompressor.java:)

使用 DependencyWalker 查看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

关于JNI程序中引用另外一个lib的更多相关文章

  1. .Net中把图片等文件放入DLL中,并在程序中引用

    原文:.Net中把图片等文件放入DLL中,并在程序中引用 [摘要] 有时我们需要隐藏程序中的一些资源,比如游戏,过关后才能看到图片,那么图片就必须隐藏起来,否则不用玩这个游戏就可以看到你的图片了,呵呵 ...

  2. C程序中引用自定义的C函数模块

    原文:C程序中引用自定义的C函数模块 我们知道,刚开始接触C语言编程,一般都是在一个.c或者.cpp(以下只说.c)的文件中编写代码,其中一定会有一个入口函数, 也就是main()函数,你可以将程序代 ...

  3. JavaScript进阶(二)在一个JS文件中引用另一个JS文件

    在一个JS文件中引用另一个JS文件       转载地址:http://blog.csdn.net/zndxlxm/article/details/7875787 方法一 在调用文件的顶部加入下例代码 ...

  4. vc++ 在程序中运行另一个程序的方法

    在vc++ 程序中运行另一个程序的方法有三个: WinExec(),ShellExcute()和CreateProcess() 三个SDK函数: WinExec,ShellExecute ,Creat ...

  5. IOS在一个程序中启动另一个程序

    尽管iPhone不允许同时运行两个应用程序,我们可以从自己的应用程序中启动另一个应用程序,并且可以在应用程序之间共享数据.我们可以使用UIApplication类的openURL:方法从一个应用程序来 ...

  6. 在一个jsp页面中引用另一个jsp文件的路径的问题

    为了提高代码的重用性,经常需要在一个jsp页面中引用另一个jsp文件的代码.关于引用时的路径的问题.下面只介绍动态引用的,我觉得静态引用的应该也一样. 相对路径: 一.在同一个文件夹下,a.jsp中引 ...

  7. 在非MFC程序中引用CString

    CString在当今软件设计界里还是小有名气的,说它是MFC中使用的最多的类一点也不过,然而在使用sdk编windows程序的时候,确不能利用CString类,只能用sdk的运行时库,比如strlen ...

  8. Android 在一个程序中启动另一个程序

    Android 开发有时需要在一个应用中启动另一个应用,比如Launcher加载所有的已安装的程序的列表,当点击图标时可以启动另一个应用.一般我们知道了另一个应用的包名和MainActivity的名字 ...

  9. php中引用&的一个小实例

    在百度知道上碰到一段关于php的引用符&的代码,对于初学都来说还是很考验理解分析能力的,把代码和自己的分析贴上来作一个备份,也与大家共勉. 代码片段: $arr =array(1,2,3,4) ...

随机推荐

  1. 多个互相有联系的checkbox的单选逻辑

    checkbox单选的状态逻辑,状态好的时候一下就写好了,状态不好的时候要调试比较久,当然主要是对其中的事件不太清楚. 先给出效果图吧. 然后给出代码, selectZhiFuBaoPay.setOn ...

  2. 尽量不要用select into 复制表

    select into 复制表会带来灾难后果,因为只是复制了一个外壳,就像克隆人,有躯体没意识,像原表的主键 外键 约束 触发器 索引都不会被复制过来, 创建一个表:CREATE TABLE [dbo ...

  3. 使用Reveal.app调试整个项目UI时间,增加LD指令 -Objc引起项目中多个静态库冲突问题

    今天接触到一个新的UI调试工具教程如下: iOS真机UI调试利器——Reveal 引入增加-ObjC -framework Reveal指令后,发现项目出现多重静态库冲突问题, 首先介绍一个指令: - ...

  4. 数据库(学习整理)----5--Oracle常用的组函数

    其他: 1.oracle中下标是从1开始的,Java下标是从0开始的 函数分类: 日期函数 字符函数 转换函数 数学函数 系统函数 ---在当前月份上面:增加.减少月份 select add_mont ...

  5. 【实习记】2014-08-20实习的mini项目总结

        实习项目总结文档 项目介绍 项目逻辑很简单,只有几个页面,只能登录,查看,支付和退款.主要作用是熟悉C++的cgi的web服务开发方式. 项目页面截图 图一:登录页面 图二:买家查看 图三:买 ...

  6. Java学习----接口

    1. interface关键字 2. 接口中的方法全部是抽象方法,不能被实例 3. 接口中的成员变量: public static final 4. 当子类实现接口的时候,必须覆盖接口中所有的方法 / ...

  7. 自定义流程gooflow.08 demo在线演示

    一.功能简介 gooflow功能清单1.自定义流程绘制2.自定义属性添加3.支持3种步骤类型 普通审批步骤 自动决策步骤 手动决策步骤 4.决策方式(支持js决策,sql语句决策) 5.审批人员参与方 ...

  8. JavaScript 高阶函数 + generator生成器

    map/reduce map()方法定义在JavaScript的Array中,我们调用Array的map()方法,传入我们自己的函数,就得到了一个新的Array作为结果: function pow(x ...

  9. ueditor富文本编辑在 asp.net MVC下使用步骤

    mvc项目中用到了这个富文本编辑就试着把遇到的问题个使用步骤在这里记录一下,希望大家少走弯路. 1.首先我们先下载net版本的uediot r.

  10. NSURLSession -- 备忘

    NSURLSession NSURLSession是iOS7出的API,在它之前常用的原生网络库是NSURLConnection,但是因为Connection的使用起来不是很方便 所以我们一直倾向于A ...