How to fix Java 15 JNI "UnsatisfiedLinkError: A dynamic link library (DLL) initialization routine failed"

How to fix Java 15 JNI "UnsatisfiedLinkError: A dynamic link library (DLL) initialization routine failed"

我发现其他人的帖子也有这个确切的错误,但到目前为止没有一个有适合我的解决方案。作为参考,以下是我发现的内容:

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

要么他们的解决方案与我的特定情况无关,要么没有解决我的问题。

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

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

它们都包含在绝对路径为C:\Users659\Documents\Programming\C++ & Java - JNI Tests的文件夹中。将命令提示符设置为当前目录,我 运行 按顺序执行以下命令:

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

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

Exception in thread "main" java.lang.UnsatisfiedLinkError: C:\Users659\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)

我在生成的 .dll 上使用了 nm 来确保函数的名称是正确的,它看起来确实是它应该的样子。

我这个小项目的全部目的是弄清楚 JNI 是如何工作的,因为我计划用 C++ 编写一小部分程序。不过,该程序的其余部分在 Java 中效果最好(对我而言)。我不知道我需要做什么才能让这个程序运行,我花了大约 2 个小时的谷歌搜索和摆弄试图让它运行。这是在 64 位 OS 上。我怎样才能制作这个程序 运行 并打印出我希望它打印出的非常少量的文本?

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

好吧,@JornVernee 有效地解决了这个问题。这是我的 C++ 标准库与正在加载的标准库之间的不匹配。我将我使用的 GCC 版本更改为更新的版本,重新编译了整个项目,程序现在可以运行了。