java.lang.UnsatisfiedLinkError - JNI

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16518490/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-16 07:15:45  来源:igfitidea点击:

java.lang.UnsatisfiedLinkError - JNI

javajava-native-interfacemingwnative

提问by user2348979

I keep getting a java.lang.UnsatisfiedLinkErrorerror every time I run my program. I have a native, a wrapper, and the program to call the native through the wrapper.

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

main.h

主文件

#ifndef __MAIN_H__
#define __MAIN_H__

#include <windows.h>
#ifdef BUILD_DLL
    #define DLL_EXPORT __declspec(dllexport)
#else
    #define DLL_EXPORT __declspec(dllimport)
#endif

#include<jni.h>
#include<iostream>

using namespace std;

extern "C"
{

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

}

#endif

main.cpp

主程序

#include "main.h"

#include<windows.h>
#include<iostream>

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");
}
}

The native was built using MinGW 64 bit. Anyway, I don't get why I get the error. Help?????

本机是使用 MinGW 64 位构建的。无论如何,我不明白为什么会出现错误。帮助?????

回答by Zax

I think the problem is that your JNI signature doesn't match. That is:

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

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

should be something like:

应该是这样的:

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

where, java_com_example should be replaced with your package name (. to be replace with _ in package name).

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

OR

或者

I would suggest you to generate your native function signature and declaration using javah -jnioption available in java.

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

回答by moskito-x

If you test with

如果你测试

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

you should use it !!

你应该使用它!

System.load(nativeFile);

There are two different ways to load a native library into a running Java program:

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

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

  • The System.loadLibrarymethod allows us to load a library from the "default" path.

    System.loadLibrary("HelloWorld");

  • System.loadallows us to load a library from anywhere via its absolute path.
    System.load("c:/path/to/dll/HelloWorld.dll");

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

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

    System.loadLibrary("HelloWorld");

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

回答by 0x8BADF00D

Another thing which could be reason for that error is missing header file when you compile our cpp library. Make sure that you included header in your cpp file.

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