So I was trying to build and load a dll into a Java application using the Jni interface, and basically I've used a few libraries consisting of the Win32 API.
The build seems to be fine, everything built and linked. But I'm not able to figure out how is the stdc++-6.dll
is not getting dynamically (shared) linked properly, while other things do according to the dependency manager as shown.
If I try to load the dll
into the java application, I get
java.lang.UnsatisfiedLinkError: C:\<path-to-dll>\libKeyboardKtx64.dll: %1 is not a valid Win32 application
I tried to do a static build (just to know not actually want a static build), but then it says
java.lang.UnsatisfiedLinkError: C:\<path-to-dll>\libKeyboardKtx64.dll: Can't find dependent libraries.
Referencing a few questions in SO, I tried debugging
- 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
Neither help, because I've did everything correctly I guess, built 64-bit dll, and trying to load it in a 64-bit Java-VM and already the dependencies inspector shows all linked libraries are 64-bit as well.
I also checked this unanswered question, it also admits the problem happens when the dll tries to reference the std lib or indirectly std::
interface, I haven't used any of them, but probably the windows libraries are using them indirectly (if I pass -nostdlib
compilation fails with unresolved reference of few symbols)
For the diagnosis, I'm attaching the Cmake file I used to build the dll and build output (from the CLI):
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