java.lang.UnsatisfiedLinkError – JNI

每次运行程序时,我都会收到java.lang.UnsatisfiedLinkError错误。 我有一个本机,一个包装器,以及通过包装器调用本机的程序。

main.h

#ifndef __MAIN_H__ #define __MAIN_H__ #include  #ifdef BUILD_DLL #define DLL_EXPORT __declspec(dllexport) #else #define DLL_EXPORT __declspec(dllimport) #endif #include #include using namespace std; extern "C" { JNIEXPORT void JNICALL native_MessageBox(string text, string title); } #endif 

main.cpp中

 #include "main.h" #include #include using namespace std; JNIEXPORT void JNICALL MsgBox(string text, string title) { MessageBox(NULL, text.c_str(), title.c_str(), MB_OK); } extern "C" DLL_EXPORT BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { switch (fdwReason) { case DLL_PROCESS_ATTACH: break; case DLL_PROCESS_DETACH: break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; } return TRUE; } 

Wrapper.java

 public class Wrapper { private static File nativeFile = null; static { //ArchitectureReader and OSReader are classes I made to read the CPU //bits and the OS ArchitectureType archType = ArchitectureReader.getArcitecture(); OSType osType = OSReader.getOS(); String filename = "C:/native-"; if (osType == OSType.Windows) { if (archType == ArchitectureType.BITS_32) filename += "win32"; else if (archType == ArchitectureType.BITS_64) filename += "win64"; else System.exit(1); } else System.exit(1); nativeFile = new File(filename + ".dll"); if (!nativeFile.exists()) System.exit(1); System.load(filename); //This is where the Exception is thrown } private static native void native_MessageBox(String text, String title); public static void MesageBox(String text, String title) { native_MessageBox(text, title); } public static String getNativePath() { return nativeFile.getAbsolutePath(); } } 

Main.Java

 public class Main { public static void main(String[] args) { Wrapper.MessageBox("Testing JNI", "JNI"); } } 

本机是使用MinGW 64位构建的。 无论如何,我不明白为什么我得到错误。 救命?????

我认为问题是你的JNI签名不匹配。 那是:

 JNIEXPORT void JNICALL native_MessageBox(string text, string title); 

应该是这样的:

 JNIEXPORT void JNICALL java_com_example_Wrapper_native_MessageBox(string text, string title); 

其中,java_com_example应替换为您的包名(。在包名中替换为_)。

要么

我建议你使用java中提供的javah -jni选项生成你的本机函数签名和声明。

如果你测试

 nativeFile = new File(filename + ".dll"); if (!nativeFile.exists()) System.exit(1); 

你应该用它!!

 System.load(nativeFile); 

将本机库加载到正在运行的Java程序有两种不同的方法:

  • System.loadLibrary(String)System.load(String)

  • System.loadLibrary方法允许我们从“默认”路径加载库。

    的System.loadLibrary( “HelloWorld” 的);

  • System.load允许我们通过其绝对路径从任何地方加载库。
    System.load("c:/path/to/dll/HelloWorld.dll") ;

另一件可能导致该错误的原因是在编译我们的cpp库时缺少头文件。 确保在cpp文件中包含标题。