如何修复Java 15 JNI"UnsatisfiedLinkError:动态链接库(DLL)初始化例程失败". [英] How to fix Java 15 JNI "UnsatisfiedLinkError: A dynamic link library (DLL) initialization routine failed"

查看:182
本文介绍了如何修复Java 15 JNI"UnsatisfiedLinkError:动态链接库(DLL)初始化例程失败".的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现其他人也有这种确切的错误,但是到目前为止,还没有一个解决方案对我有用.供参考,这是我发现的东西:

https://community.oracle.com/tech/developers/discussion/2233828/jni-link-error-a-dynamic-link-library-dll-initialization-routine-failed

JNI UnsatisfiedLinkError:动态链接库(DLL)初始化例程失败

https://www.debugcn.com/en/article/5175409.html

https://coderanch.com/t/132356/engineering/java-lang-UnsatisfiedLinkError

他们的解决方案与我的特定情况无关,或者没有为我解决问题.

使用Windows 10计算机在命令行上编译所有内容,并使用GCC(gcc-5.1.0-tdm64-1-c ++)将C ++部分编译为.dll和JDK 15.0.1的javac工具.这里有三个相关文件,一个是从java文件派生的头文件.

Main.java:

 公共类Main {静止的 {System.load("C:\\ Users \\ 17659 \\ Documents \\ Programming \\ C ++& Java-JNI Tests \\ library.dll");//System.loadLibrary("library);}公共静态void main(String [] args){新的Main().outputText();}私有原生void outputText();} 

Main.h:

 <代码>/*请勿编辑此文件-它是机器生成的*/#include< jni.h>/* Main类的标题*/#ifndef _Included_Main#define _Included_Main#ifdef __cplusplus外部"C"{#万一/**类别:主要*方法:outputText*签名:()V*/JNIEXPORT void JNICALL Java_Main_outputText(JNIEnv *,jobject);#ifdef __cplusplus}#万一#万一 

Library.cpp:

  #include< iostream>#include"Main.h"JNIEXPORT void JNICALL Java_Main_outputText(JNIEnv * a,jobject b){std :: cout<<测试";} 

它们全部包含在文件夹中,绝对路径为C:\ Users \ 17659 \ Documents \ Programming \ C ++&Java-JNI测试.将命令提示符设置为当前目录,我按顺序运行以下命令:

  g ++ -c -o Library.o -I"C:\ Users \ 17659 \ Documents \ jdk-15.0.1 \ include"-I"C:\ Users \ 17659 \ Documents \ jdk-15.0.1 \ include \ win32"库.cppg ++ -shared -o library.dll Library.ojavac Main.javaJava Main 

尽管我尝试了多种方法,但我总是遇到相同的错误:

 线程"main"中的异常;java.lang.UnsatisfiedLinkError:C:\ Users \ 17659 \ Documents \ Programming \ C ++&Java-JNI Tests \ library.dll:动态链接库(DLL)初始化例程失败在java.base/jdk.internal.loader.NativeLibraries.load(本机方法)在java.base/jdk.internal.loader.NativeLibraries $ NativeLibraryImpl.open(NativeLibraries.java:383)在java.base/jdk.internal.loader.NativeLibraries.loadLibrary(NativeLibraries.java:227)在java.base/jdk.internal.loader.NativeLibraries.loadLibrary(NativeLibraries.java:169)在java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2407)在java.base/java.lang.Runtime.load0(Runtime.java:747)在java.base/java.lang.System.load(System.java:1857)< clinit>(Main.java:3) 

我在生成的.dll上使用了 nm 来确保函数名称正确,并且看起来确实正确.

我的这个小项目的重点是弄清楚JNI的工作原理,因为我计划用C ++编写一小部分程序.不过,该程序的其余部分在Java(对我而言)中效果最好.我不知道要使该程序正常工作我需要做什么,我花了大约2个小时的时间来进行搜索和摆弄,以使其正常运行.这是在64位OS上.如何使该程序运行并打印出我希望打印的少量文本?

更新:根据 @JornVernee 删除行 #include< iostream> ,然后将 std :: cout 替换为 printf()以写入控制台确实有效.所以我的问题现在变成了:为什么包括标准的C ++标头会导致错误?

解决方案

好吧, @JornVernee 有效地钉牢了正确地发布在头上.我在C ++中使用的标准库与正在加载的标准库之间不匹配.我将使用的GCC版本更改为最新版本,重新编译了整个项目,该程序现在可以正常工作.

I have found other posts of people having this exact error, but not one thus far has had a solution that worked for me. For reference, here are the things I have found:

https://community.oracle.com/tech/developers/discussion/2233828/jni-link-error-a-dynamic-link-library-dll-initialization-routine-failed

JNI UnsatisfiedLinkError: A dynamic link library (DLL) initialization routine failed

https://www.debugcn.com/en/article/5175409.html

https://coderanch.com/t/132356/engineering/java-lang-UnsatisfiedLinkError

Either their solution was not relevant to my particular scenario, or it did not fix the issue for me.

Everything is being compiled on the command line with a Windows 10 computer and using GCC (gcc-5.1.0-tdm64-1-c++) for compiling the C++ portions into a .dll, and JDK 15.0.1's javac tool. There are three relevant files here, one being the header file derived from the java file.

Main.java:

public class Main {
    static {
        System.load("C:\\Users\\17659\\Documents\\Programming\\C++ & Java - JNI Tests\\library.dll");
        //System.loadLibrary("library");
    }
    public static void main(String[] args) {
        new Main().outputText();
    }
    
    private native void outputText();
}

Main.h:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Main */

#ifndef _Included_Main
#define _Included_Main
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     Main
 * Method:    outputText
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_Main_outputText
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

Library.cpp:

#include <iostream>
#include "Main.h"

JNIEXPORT void JNICALL Java_Main_outputText(JNIEnv * a, jobject b)
{
    std::cout << "testing";
}

They are contained all within the folder with the absolute path of C:\Users\17659\Documents\Programming\C++ & Java - JNI Tests. With a command prompt set to that as the current directory, I run the following commands in order:

g++ -c -o Library.o -I"C:\Users\17659\Documents\jdk-15.0.1\include" -I"C:\Users\17659\Documents\jdk-15.0.1\include\win32" Library.cpp
g++ -shared -o library.dll Library.o
javac Main.java
java Main

Despite the multiple things I have tried, I always get this same error:

Exception in thread "main" java.lang.UnsatisfiedLinkError: C:\Users\17659\Documents\Programming\C++ & Java - JNI Tests\library.dll: A dynamic link library (DLL) initialization routine failed
        at java.base/jdk.internal.loader.NativeLibraries.load(Native Method)
        at java.base/jdk.internal.loader.NativeLibraries$NativeLibraryImpl.open(NativeLibraries.java:383)
        at java.base/jdk.internal.loader.NativeLibraries.loadLibrary(NativeLibraries.java:227)
        at java.base/jdk.internal.loader.NativeLibraries.loadLibrary(NativeLibraries.java:169)
        at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2407)
        at java.base/java.lang.Runtime.load0(Runtime.java:747)
        at java.base/java.lang.System.load(System.java:1857)
        at Main.<clinit>(Main.java:3)

I have used nm on the resulting .dll to make sure the name of the function is correct, and it does seem to be exactly as it should.

The entire point of this little project of mine is to figure out how JNI works, since I have a plan to write a small portion of a program in C++. The rest of the program though would work best in Java (for me). I do not know what I need to do to get this program to work, I have spent approximately 2 hours of googling and fiddling attempting to get it to function. This is on a 64-bit OS. How can I make this program run and print out the very little amount of text I would like it to print out?

Update: As per @JornVernee removing the line #include <iostream> and replacing the std::cout with a printf() to write to the console did actually work. So my question now becomes this: why does including a standard C++ header cause an error?

解决方案

Well, @JornVernee effectively nailed the issue right on the head. It was a mismatch between the standard library I had for C++ and the one being loaded. I changed the version of GCC I was using to a more up-to-date version, recompiled the entire project, and the program works now.

这篇关于如何修复Java 15 JNI"UnsatisfiedLinkError:动态链接库(DLL)初始化例程失败".的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆