【发布时间】:2021-04-28 04:55:30
【问题描述】:
所以我尝试使用 Jni 接口构建 dll 并将其加载到 Java 应用程序中,基本上我使用了一些由 Win32 API 组成的库。
构建似乎很好,所有内容都已构建和链接。但我无法弄清楚stdc++-6.dll 是如何没有正确动态(共享)链接的,而其他事情则根据依赖管理器进行,如图所示。
如果我尝试将 dll 加载到 java 应用程序中,我会得到
java.lang.UnsatisfiedLinkError: C:\<path-to-dll>\libKeyboardKtx64.dll: %1 is not a valid Win32 application
我试图做一个静态构建(只是为了知道实际上并不想要一个静态构建),但是它说
java.lang.UnsatisfiedLinkError: C:\<path-to-dll>\libKeyboardKtx64.dll: Can't find dependent libraries.
参考SO中的几个问题,我尝试调试
- JNI C++ DLL - 'UnsatisfiedLinkError: %1 is not a valid Win32 application'
- JNI %1 is not a valid Win32 application
- java.io.IOException: %1 is not a valid Win32 application
没有帮助,因为我猜我做的一切都是正确的,构建了 64 位 dll,并尝试在 64 位 Java-VM 中加载它,并且依赖项检查器已经显示所有链接库也是 64 位的.
我还检查了this unanswered question,它也承认当 dll 尝试引用 std lib 或间接引用 std:: 接口时会发生问题,我没有使用它们中的任何一个,但可能是 windows 库间接使用它们(如果我通过-nostdlib 编译失败,未解决几个符号的引用)
为了诊断,我附上了我用来构建 dll 和构建输出(来自 CLI)的 Cmake 文件:
cmake_minimum_required(VERSION 3.10)
project(KeyboardKt)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s")
option(ARCH "architecture")
add_definitions(-D_WIN32_WINNT=0x600)
include_directories($ENV{JNI_HEADERS_DIR})
include_directories("../../generated/jni")
include_directories("../../../nativeCommon/windows")
add_library(
KeyboardKt${ARCH} SHARED
JvmKeyboardHandler.cpp
)
== Using MXE wrapper: /usr/src/mxe/usr/bin/x86_64-w64-mingw32.shared-cmake
- cmake version 3.19.2
- warnings for unused CMAKE_POLICY_DEFAULT variables can be ignored
== Using MXE toolchain: /usr/src/mxe/usr/x86_64-w64-mingw32.shared/share/cmake/mxe-conf.cmake
== Using MXE runresult: /usr/src/mxe/usr/share/cmake/modules/TryRunResults.cmake
== Adding "-DCMAKE_BUILD_TYPE=Release"
loading initial cache file /usr/src/mxe/usr/share/cmake/modules/TryRunResults.cmake
-- The C compiler identification is GNU 10.2.0
-- The CXX compiler identification is GNU 10.2.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/src/mxe/usr/bin/x86_64-w64-mingw32.shared-gcc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/src/mxe/usr/bin/x86_64-w64-mingw32.shared-g++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /work/project/build/tmp/compile-jni-windows-x64
== Using MXE wrapper: /usr/src/mxe/usr/bin/x86_64-w64-mingw32.shared-cmake
== Skip using MXE toolchain: /usr/src/mxe/usr/x86_64-w64-mingw32.shared/share/cmake/mxe-conf.cmake
Scanning dependencies of target KeyboardKtx64
[ 50%] Building CXX object CMakeFiles/KeyboardKtx64.dir/JvmKeyboardHandler.cpp.obj
[100%] Linking CXX shared library libKeyboardKtx64.dll
[100%] Built target KeyboardKtx64
【问题讨论】:
-
libstdc++-6.dll不是与 Windows 捆绑在一起的库,因此您必须确保它位于 standard DLL search path 上(例如,将包含该库的目录添加到 PATH 变量中)跨度> -
您还需要确保您使用的是与您的 JVM 相同的 C++ 运行时库。请参阅C++ JNI crashes/hangs when doing any IO/Streams,了解如果链接到与 JVM 使用的不同的 C++ 运行时库会发生什么情况的示例。
标签: java c++ windows dll java-native-interface