dll打包到jar文件中调用的问题

Karnak 2002-03-28 12:24:12
我现在做一个applet,但是要用到dll,所以我想把dll打包到jar中一块下载到客户端。
我试了一下,发现打包后调用时找不到dll,不知道是怎么回事,请指教。
假设我的class和dll都放在org下,可以找到class,但是class调用dll时出异常java.lang.UnsatisfiedLinkError
...全文
1464 31 打赏 收藏 转发到动态 举报
写回复
用AI写文章
31 条回复
切换为时间正序
请发表友善的回复…
发表回复
idpmud 2002-04-03
  • 打赏
  • 举报
回复
对不起,不能很仔细的看你的程序,你命令行已经执行过了,如果在jbuilder
中出现问题的话,我猜可能是jbuilder需要独立的设置自己的环境,你可以查一下它的帮助,我没有使过jbuilder,我以前作的都是需要跨平台的Package,所以帮不了你了。
Karnak 2002-04-03
  • 打赏
  • 举报
回复
我现在越来越困惑了:
1、我的jni在命令行执行过了,没有问题。
2、我用jbuilder做了个application也不能调用。package demo
错误提示:
java.lang.UnsatisfiedLinkError: Crypt_Get_Version_Proxy

at demo.softCertProxy.Crypt_Get_Version_Proxy(Native Method)

at demo.softCertProxy.Crypt_Get_Version_Java

我不知道是不是用jbuilder一类工具调用时需要做什么改变,我把大体代码写出请大家提意见!
code of softCertProxy .java

package demo;
public class softCertProxy
{
public native int Crypt_Get_Version_Proxy(byte[] version);

static byte[] version=new byte[10];

static
{
try
{
System.loadLibrary("soft_cert_proxy");
}
catch(SecurityException e)
{
System.err.println("security failed "+e);
}
}

//获取版本号2.0
public int Crypt_Get_Version_Java(byte[] version)
{
if (Crypt_Get_Version_Proxy(version) ==0)
{
System.out.println("The currently version is "+new String(version));

return 0;
}
else
System.out.println("Get version failed");

return 1;
}
}

code of softCertProxy .c

#include <stdio.h>
#include <windows.h>
#include "softCertProxy.h"

typedef UINT (CALLBACK* CRYPT_GET_VERSION_DLL)(char *);

//获取版本号2.0
JNIEXPORT jint JNICALL Java_softCertProxy_Crypt_1Get_1Version_1Proxy
(JNIEnv * jEnv, jobject this, jbyteArray version)
{
HINSTANCE hDLL;
CRYPT_GET_VERSION_DLL Crypt_Get_Version_Dll;
int flag =1;

hDLL =LoadLibrary("soft_cert");
Crypt_Get_Version_Dll =(CRYPT_GET_VERSION_DLL)GetProcAddress(hDLL,"Crypt_Get_Version");
if (!Crypt_Get_Version_Dll)
{
// handle the error
FreeLibrary(hDLL);
printf("dll link failed\n");
return flag;
}
else
{
jboolean* Version;

Version =(*jEnv)->GetByteArrayElements(jEnv,version,0);
// call the function
if(Crypt_Get_Version_Dll(Version) ==0)
{
flag =0;
(*jEnv)->ReleaseByteArrayElements(jEnv,version,Version,0);
}

return flag;
}
}

code of jbuilder
我就写我调用的那一部分
softCertProxy scp =new softCertProxy();
byte[] version =new byte[10];
if(scp.Crypt_Get_Version_Java(version) ==0)
{
String aa =new String(version);
messagePane.showMessageDialog(null,"取得版本号为:"+aa,"报告",JOptionPane.INFORMATION_MESSAGE);
}
Karnak 2002-04-03
  • 打赏
  • 举报
回复
我现在越来越困惑了:
1、我的jni在命令行执行过了,没有问题。
2、我用jbuilder做了个application也不能调用。package demo
错误提示:
java.lang.UnsatisfiedLinkError: Crypt_Get_Version_Proxy

at demo.softCertProxy.Crypt_Get_Version_Proxy(Native Method)

at demo.softCertProxy.Crypt_Get_Version_Java

我不知道是不是用jbuilder一类工具调用时需要做什么改变,我把大体代码写出请大家提意见!
code of softCertProxy .java

package demo;
public class softCertProxy
{
public native int Crypt_Get_Version_Proxy(byte[] version);

static byte[] version=new byte[10];

static
{
try
{
System.loadLibrary("soft_cert_proxy");
}
catch(SecurityException e)
{
System.err.println("security failed "+e);
}
}

//获取版本号2.0
public int Crypt_Get_Version_Java(byte[] version)
{
if (Crypt_Get_Version_Proxy(version) ==0)
{
System.out.println("The currently version is "+new String(version));

return 0;
}
else
System.out.println("Get version failed");

return 1;
}
}

code of softCertProxy .c

//获取版本号2.0
JNIEXPORT jint JNICALL Java_softCertProxy_Crypt_1Get_1Version_1Proxy
(JNIEnv * jEnv, jobject this, jbyteArray version)
{
HINSTANCE hDLL;
CRYPT_GET_VERSION_DLL Crypt_Get_Version_Dll;
int flag =1;

hDLL =LoadLibrary("soft_cert");
Crypt_Get_Version_Dll =(CRYPT_GET_VERSION_DLL)GetProcAddress(hDLL,"Crypt_Get_Version");
if (!Crypt_Get_Version_Dll)
{
// handle the error
FreeLibrary(hDLL);
printf("dll link failed\n");
return flag;
}
else
{
jboolean* Version;

Version =(*jEnv)->GetByteArrayElements(jEnv,version,0);
// call the function
if(Crypt_Get_Version_Dll(Version) ==0)
{
flag =0;
(*jEnv)->ReleaseByteArrayElements(jEnv,version,Version,0);
}

return flag;
}
}

code of jbuilder
我就写我调用的那一部分
softCertProxy scp =new softCertProxy();
byte[] version =new byte[10];
if(scp.Crypt_Get_Version_Java(version) ==0)
{
String aa =new String(version);
messagePane.showMessageDialog(null,"取得版本号为:"+aa,"报告",JOptionPane.INFORMATION_MESSAGE);
}
Karnak 2002-04-02
  • 打赏
  • 举报
回复
我现在直接在jbuilder下都不能调用,还没有在html里面试呢,奇怪了,可以找到dll,但是就不让我调用里面的方法!我用命令行执行是没有问题的!
这也有沙盒限制吗?
wake2000 2002-04-02
  • 打赏
  • 举报
回复
java在网页方面安全性有点过头了。我改了本地的runtime env中的安全限制文件

jre/lib/security中的java.policy文件:

增加以下内容:

grant codeBase "http://192.168.0.1/*" {
permission java.security.AllPermission;
};

之后我爱干什么就干什么,java就不理applet中的权限了。

不过动态连接库好象是没有办法自动下载到浏览器端。

idpmud(泥潭) :我的浏览器端是在linux平台上;如果在linux平台上有ActiveX,那么我就没有必要费这么大劲了。
Karnak 2002-04-02
  • 打赏
  • 举报
回复
我在计算机世界上看到一篇文章,里面说不要试图做下载调用本地方法的applet
idpmud 2002-04-01
  • 打赏
  • 举报
回复
Karnak(神庙) 如果你把dll放入system32还出现调用错误的话,你可以重新启动服务器的,建议你使用环境变量设定LD_LIBRARY_PATH。
wake2000(coucou) 你说的情况我没有遇到过,因为如果有在客户端的调用需要的话,在设计之初就应该选用ActiceX或者全交给Java来处理,而不应该试图调用JNI想重用以前的库,但是我想基于本地方法调用的话,在Applet上可能行不通,我再调查一下吧,可惜我现在负责的是IDP汇编的项目,要不,我就有时间和资源了。
johnbull588 2002-04-01
  • 打赏
  • 举报
回复
up
Karnak 2002-04-01
  • 打赏
  • 举报
回复
idpmud(泥潭) 问题是我现在把dll放在windows\system32下都报错,你说这是怎么回事呢?
Karnak 2002-03-29
  • 打赏
  • 举报
回复
wake2000(coucou)
我这可是要基于internet的,不可能让客户去做这些修改,你试的怎么样了?
wake2000 2002-03-29
  • 打赏
  • 举报
回复
idpmud(泥潭)

如果是在服务器端执行jni的话,是可以通过LD_LIBRARY_PATH来定义的库的路径的,但是如果你的java程序程序在服务器端,要通过http传送到客户端,并且把动态连接库也下载到客户端,并且让客户端通过浏览器在本地执行的话,你是否考虑过如何修改客户端的LD_LIBRARY_PATH的环境变量?

我觉得目前我是在做linux环境下的类似ActiveX的工作。

如果让客户端执行网络上下载的程序,会牵涉到安全问题,但是可以通过policytool程序或者是修改java/security/java.policy文件中的内容信赖指定url或签名的服务器java程序。

另外在linux上下静态库没有什么特别的吧?cc 直接编译就可以,我用的是动态库。cc 加上 -shared 选项。

编辑器用什么都无关紧要,vi、joe、pico甚至在windows平台上用写字板写完再传过来都无所谓。
zhipop 2002-03-29
  • 打赏
  • 举报
回复
学习中。。。。。。。。。。
idpmud 2002-03-29
  • 打赏
  • 举报
回复
怎么可以直接在程序里写入具体的地址呢?另外,你的开发工具是什么,为什么程序的定义都这么怪?在linux下你用什么写静态库的,vi?
wake2000 2002-03-29
  • 打赏
  • 举报
回复
不过我现在用jar打包还是找不到 .so 文件。不知道如何将动态连接库自动下载到客户端。

没有心思吃晚饭。
idpmud 2002-03-29
  • 打赏
  • 举报
回复
大错特错了,我以前作JNI调用的时候,在linux和saloris下,都是设置LD_LIBRARY_PATH = $jni
export LD_LIBRARY_PATH
$/userhome/sh .profile
这样才可以的,肯定不会报JNI错误,在Windows下导入这个环境变量也一样,但是当你把dll放入系统目录肯定也行的。
而你上面的作法会有问题的。
wake2000 2002-03-29
  • 打赏
  • 举报
回复
没有办法。你用

static
{
try
{
System.load("c:/path/to/dll/soft_cert_proxy.dll");
}
catch(SecurityException e)
{
System.err.println("security failed "+e);
}
}

试试。
Karnak 2002-03-29
  • 打赏
  • 举报
回复
JNIEXPORT jint JNICALL Java_softCertProxy_Crypt_1Get_1Version_1Proxy
(JNIEnv * jEnv, jobject this, jbyteArray version)
{
HINSTANCE hDLL;
CRYPT_GET_VERSION_DLL Crypt_Get_Version_Dll;
int flag =1;

hDLL =LoadLibrary("soft_cert");
Crypt_Get_Version_Dll =(CRYPT_GET_VERSION_DLL)GetProcAddress(hDLL,"Crypt_Get_Version");
if (!Crypt_Get_Version_Dll)
{
// handle the error
FreeLibrary(hDLL);
printf("dll link failed\n");
return flag;
}
else
{
jboolean* Version;

Version =(*jEnv)->GetByteArrayElements(jEnv,version,0);
// call the function
if(Crypt_Get_Version_Dll(Version) ==0)
{
flag =0;
(*jEnv)->ReleaseByteArrayElements(jEnv,version,Version,0);
}

return flag;
}
}
我是这样调用的,这是.c文件

static
{
try
{
System.loadLibrary("soft_cert_proxy");
}
catch(SecurityException e)
{
System.err.println("security failed "+e);
}
}
这是java装载dll
wake2000 2002-03-29
  • 打赏
  • 举报
回复
是不是你用loadLibrary()时,将.dll的后缀名也写进去了?
wake2000 2002-03-29
  • 打赏
  • 举报
回复
不会吧?你把调用jni的那部分程序贴出来look1look.
wake2000 2002-03-29
  • 打赏
  • 举报
回复
搞定了。

System.load()调用动态连接库时取绝对路径。而System.loadLibrary()取环境变量中的路径。

在调用动态连接库时用System.load( CurrentPath + "/libtest.so" )调用动态库,其中CurrentPath用System.getProperty( "user.dir" )取得当前路径。动态连接库的文件名写齐。

“今晚做梦也会笑”,哈哈哈

加载更多回复(11)

23,407

社区成员

发帖
与我相关
我的任务
社区描述
Java 非技术区
社区管理员
  • 非技术区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧