我已经查看了StackOverFlow和其他搜索引擎中的UnsatisfiedLinkError帮助,但是解决方案还没有满足问题所以我会在这里说明。
我正在尝试对PKCS11 DLL库进行JNI调用,我收到以下错误:
Exception in thread "main" java.lang.UnsatisfiedLinkError: org.thotheolh.jche.NativeBridge.loadPKCS11Module(Ljava/lang/String;)V
at org.thotheolh.jche.NativeBridge.loadPKCS11Module(Native Method)
at org.thotheolh.jche.NativeBridge.load(NativeBridge.java:40)
at org.thotheolh.jche.NativeBridge.<init>(NativeBridge.java:29)
at org.thotheolh.jche.exception.test.PKCS11GenericTest.main(PKCS11GenericTest.java:27)
Java Result: 1
我的本机桥接片段我曾经在下面进行“原生”调用:
NativeBridge.java
public class NativeBridge {
private String pkcs11Module;
private String pkcs11JavaWrapper = "libJPKCS11";
public NativeBridge(String pkcs11Module) throws IOException, NoSuchFieldException {
this.pkcs11Module = pkcs11Module;
load();
}
public void load() throws IOException, NoSuchFieldException {
System.loadLibrary(pkcs11JavaWrapper);
loadPKCS11Module(pkcs11Module);
}
public synchronized native void loadPKCS11Module(String location) throws IOException;
}
javah生成的Header File片段:
JCHE.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class org_thotheolh_jche_NativeBridge */
#ifndef _Included_org_thotheolh_jche_NativeBridge
#define _Included_org_thotheolh_jche_NativeBridge
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: org_thotheolh_jche_NativeBridge
* Method: loadPKCS11Module
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_org_thotheolh_jche_NativeBridge_loadPKCS11Module
(JNIEnv *, jobject, jstring);
#ifdef __cplusplus
}
#endif
#endif
C文件摘要:
JCHE.c
#include <jni.h>
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include "JCHE.h"
const char *pkcs11ModuleFileLoc;
HMODULE pkcs11;
JNIEXPORT void JNICALL Java_org_thotheolh_jche_NativeBridge_loadPKCS11Module
(JNIEnv *env, jobject obj, jstring location) {
printf("inside native method\n");
pkcs11ModuleFileLoc = (*env)->GetStringUTFChars(env, location, (jboolean *)0);
printf("%s", pkcs11ModuleFileLoc);
//pkcs11 = LoadLibraryA(pkcs11ModuleFileLoc);
//printf("\nLoaded PKCS11 Lib");
}
我试图在Java中检查加载的库并发现它们已经加载但是不知何故我得到了所描述的错误,尽管通过许多其他方法可以尝试解决这个问题。
答案 0 :(得分:1)
我尝试了但无法重现您的问题(但我使用了Linux并将System.loadLibrary("libJPKCS11");
更改为System.loadLibrary("JPKCS11");
,请参阅下文,但我确信这不会导致您的问题,因为错误消息会有所不同)。
您获得的错误消息表示可以加载库,因此调用System.loadLibrary()
没有问题。
您确定JCHE.obj
是libJPKCS11.dll
的成员,即libJPKCS11.dll
是否正确链接,并且JCHE.obj
是否使用正确的标志来构建DLL?对我来说,该消息看起来好像正确加载了库,但不包含函数Java_org_thotheolh_jche_NativeBridge_loadPKCS11Module()
。因此,您可能想要检查libJPKCS11.dll
实际上是否“完整”和“是最新的”。
顺便说一句,您可以考虑删除lib
前缀。 System.loadLibrary
负责前缀和后缀。您只能使用System.loadLibrary("foo");
。然后它在Windows上加载libfoo.so
,在Windows上加载foo.dll
。否则它会尝试在POSIX上加载liblibfoo.so
,感觉很奇怪。
答案 1 :(得分:0)
找到一个非常古老的2012 Netbeans帖子来解决问题。这是由于在制作DLL文件时缺少一些GCC编译器选项。
其他GCC编译器选项:
-Wl,--export-all-symbols -Wl,--add-stdcall-alias