C++ 使用JNI自定义本机代码使我的应用程序在32位Windows 10环境下工作,但获得;不满意的链接错误可能';“找不到依赖库”;
我目前遇到一个问题,就是如何让我的应用程序App(在EclipseRCP下编写和构建)在32位Windows10环境下工作 下面是背景,我最近通过在C++本地代码中嵌入这种能力,实现了一个使用JNI的Windows关机阻断器功能。因此,我生成了两个版本的dll(使用Cygwin–mingw32功能),一个用于64位(与我的开发人员pc相同),另一个用于32位。然后将它们绑定到OSGi绑定本机代码中。最后,应用程序被打包并构建到一个可以部署到客户端机器的.exe中。有些客户使用32位Windows,所以我必须满足它 为了测试这一点,我在安装了Windows 10 32位操作系统(Windows评估许可证)的情况下,使用pc的Hyper-V功能设置了一个vm。在那里部署了我的应用程序,并尝试启动启动Windows关机阻止程序功能的活动 然后我在日志中发现以下错误(在我的64位Windows主机环境中,我没有发现这个问题,它工作得很好): 我如何生成.dll文件的端到端过程如下所示:C++ 使用JNI自定义本机代码使我的应用程序在32位Windows 10环境下工作,但获得;不满意的链接错误可能';“找不到依赖库”;,c++,dll,java-native-interface,32-bit,unsatisfiedlinkerror,C++,Dll,Java Native Interface,32 Bit,Unsatisfiedlinkerror,我目前遇到一个问题,就是如何让我的应用程序App(在EclipseRCP下编写和构建)在32位Windows10环境下工作 下面是背景,我最近通过在C++本地代码中嵌入这种能力,实现了一个使用JNI的Windows关机阻断器功能。因此,我生成了两个版本的dll(使用Cygwin–mingw32功能),一个用于64位(与我的开发人员pc相同),另一个用于32位。然后将它们绑定到OSGi绑定本机代码中。最后,应用程序被打包并构建到一个可以部署到客户端机器的.exe中。有些客户使用32位Windows
public class ShutdownBlocker {
private static boolean nativeLibLoaded;
public static void loadLibrary() {
if(!nativeLibLoaded) {
System.loadLibrary("ShutdownBlocker");
nativeLibLoaded=true;
}
}
public static native void shutdownBlockReasonCreate(String title, String reasonText);
public static native void shutdownBlockReasonDestroy(String title);
}
这是.h文件
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_app_service_util_shutdown_ShutdownBlocker */
#ifndef _Included_com_app_service_util_shutdown_ShutdownBlocker
#define _Included_com_app_service_util_shutdown_ShutdownBlocker
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_app_service_util_shutdown_ShutdownBlocker
* Method: shutdownBlockReasonCreate
* Signature: (Ljava/lang/String;Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_com_app_service_util_shutdown_ShutdownBlocker_shutdownBlockReasonCreate
(JNIEnv *, jclass, jstring, jstring);
/*
* Class: com_app_service_util_shutdown_ShutdownBlocker
* Method: shutdownBlockReasonDestroy
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_com_app_service_util_shutdown_ShutdownBlocker_shutdownBlockReasonDestroy
(JNIEnv *, jclass, jstring);
#ifdef __cplusplus
}
#endif
#endif
对于32位窗口
x86_64-w64-mingw32-g++ -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/win32" -Wl,"C:\Windows\System32\comctl32.dll" -shared -o ShutdownBlocker.dll /cygdrive/c/dale/eclipse-rcp-workspace/App/development/shutdown/ShutdownBlocker.cpp
i686-w64-mingw32-g++ -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/win32" -Wl,--enable-stdcall-fixup "C:\Windows\SysWOW64\comctl32.dll" -shared -o ShutdownBlocker.dll /cygdrive/c/dale/eclipse-rcp-workspace/App/development/shutdown/ShutdownBlocker.cpp
- 更新build.properties
- 更新MANIFEST.MF。在此处粘贴相关部分:
setup32bit.exe
(如上所述)C:\Users\Dale >depends.exe ShutdownBlocker.dll
!ENTRY org.eclipse.ui 4 0 2020-01-22 16:57:22.218
!MESSAGE Unhandled event loop exception
!STACK 0
java.lang.UnsatisfiedLinkError: com.app.service.util.shutdown.ShutdownBlocker.shutdownBlockReasonCreate(Ljava/lang/String;Ljava/lang/String;)V
(不确定我是否仍然可以在这里讨论这个问题,或者我需要创建一个新问题?不确定实际问题,将DLL置于PATH中应该可以工作。为了确保这一点,请检查它们是否都是32位dll,尤其是msvcrt.dll。一些观察结果:A)您可以忽略Dependency Walker中的“API-MS-WIN-CORE”错误条目,它们在您的情况下并不重要。b) 为了使屏幕截图更有用,您应该折叠除第一级树之外的所有树(c)一旦解决此问题,您将得到更多不满意的链接错误,因为您导出的函数缺少前导下划线(cygin gcc中有一个编译器选项可以获得它们),谢谢@user2543253,根据你的评论,我进一步研究了依赖项遍历程序,发现我的32位ShutdownBlocker.dll不知何故依赖于64位libstdc++-6.dll(有点奇怪)。我一开始不知道我是怎么做到的。因此,我再次将64位libstdc++-6.dll复制到路径位置,得到了另一个错误“未满足的链接错误:…ShutdownBlocker.dll:%1不是有效的Win32应用程序”,这是意料之中的。看来我需要重温一下我是如何编译32位dll的。我在文章中附上了一个依赖性行者的截图。你如何编译你的32/64位库没有问题。如果Dependency Walker显示一个64位DLL,这并不意味着lib需要一个64位DLL,但Dependency Walker找到了一个64位DLL,它不适用于32位应用程序,而不是正确的32位DLL。您必须确保您确实复制了32位DLL(为了安全起见,请从路径中删除libstdc++.DLL的所有64位副本)。好的,忘了这一点,您同时解决了它,我并没有阅读您更新的问题。您的新问题就是我前面提到的带下划线的问题。我想我解决了上一个问题(未满足的链接错误),基本上是通过在我的g++编译中包含“-Wl,--add stdcall alias”标志来删除此错误。这个解决方案可以在JNI教程()的“(Windows)32位JDK[过时?]”部分找到。非常感谢@user2543253的建议!我要做几件事
i686-w64-mingw32-g++ -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/win32" -Wl,--enable-stdcall-fixup "C:\Windows\SysWOW64\comctl32.dll" -shared -o ShutdownBlocker.dll /cygdrive/c/dale/eclipse-rcp-workspace/App/development/shutdown/ShutdownBlocker.cpp
Bundle-NativeCode: lib/shutdown/windows-amd64/ShutdownBlocker.dll;
processor=x86_64,
lib/shutdown/windows-i686/ShutdownBlocker.dll;
processor=x86, *
C:\Users\Dale >depends.exe ShutdownBlocker.dll
$ objdump -p ShutdownBlocker.dll | grep DLL
DLL
vma: Hint Time Forward DLL First
DLL Name: KERNEL32.dll
DLL Name: msvcrt.dll
DLL Name: USER32.dll
DLL Name: libstdc++-6.dll
DLL Name: COMCTL32.dll
!ENTRY org.eclipse.ui 4 0 2020-01-22 16:57:22.218
!MESSAGE Unhandled event loop exception
!STACK 0
java.lang.UnsatisfiedLinkError: com.app.service.util.shutdown.ShutdownBlocker.shutdownBlockReasonCreate(Ljava/lang/String;Ljava/lang/String;)V