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"
我发现其他人的帖子也有这个确切的错误,但到目前为止没有一个有适合我的解决方案。作为参考,以下是我发现的内容:
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 版本更改为更新的版本,重新编译了整个项目,程序现在可以运行了。
我发现其他人的帖子也有这个确切的错误,但到目前为止没有一个有适合我的解决方案。作为参考,以下是我发现的内容:
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 版本更改为更新的版本,重新编译了整个项目,程序现在可以运行了。