我的dll代码可以从exe文件工作,但无法从Java loadLibrary加载 < >我创建了一个C++模块,用于构建共享库文件,然后使用JNI ./P>调用java。 我有2个环境,Windows和UNIX,我有一个C++可执行程序和一个java程序,我只是为每个环境重新编译。p> 当我在Unix中编译tester.exe程序并使用方法运行它时 从我的图书馆(.so)它工作得很好 当我在Unix中编译Java程序并加载库(.so)时 Java的loadLibrary,它运行良好
当我在Windows中编译tester.exe程序并使用 方法从我的库(.dll)它工作正常。就像unix一样 版本我的dll代码可以从exe文件工作,但无法从Java loadLibrary加载 < >我创建了一个C++模块,用于构建共享库文件,然后使用JNI ./P>调用java。 我有2个环境,Windows和UNIX,我有一个C++可执行程序和一个java程序,我只是为每个环境重新编译。p> 当我在Unix中编译tester.exe程序并使用方法运行它时 从我的图书馆(.so)它工作得很好 当我在Unix中编译Java程序并加载库(.so)时 Java的loadLibrary,它运行良好,java,dll,java-native-interface,loadlibrary,Java,Dll,Java Native Interface,Loadlibrary,当我在Windows中编译tester.exe程序并使用 方法从我的库(.dll)它工作正常。就像unix一样 版本 在Windows中编译Java程序并用Java的loadLibrary加载库(.dll)时失败。上面写着试图进入 无效地址。 我不明白为什么它在Windows中运行时不能与Java loadLibrary一起工作,但它在其他任何地方都可以使用相同的代码。如果延迟加载库使用的依赖DLL,则库将以Java加载,但不起作用。我知道有一些代码会导致java加载我的库,但是我不能理解为什
我的dll有一个公开的方法,它从一些现有库中调用4个方法。如果我注释掉这4个方法,那么我的dll将以Java格式加载。我知道这与我的dll链接到的库中的这些方法有关。Java对依赖库的看法有什么不同吗?我尝试先加载依赖库,但加载的一个dll文件导致递归错误,堆栈溢出 有人知道一种解决DLL的方法,它会导致递归错误导致堆栈溢出吗?我需要其中的方法,但无法使用java loadLibrary加载它
下面是有关涉及的文件和实际错误消息的更多详细信息。 我在我的初始dll文件中添加了一个DllMain,以查看加载的内容和时间。如果我把同一个程序(我的普通dll到调用JNIDLL)编译成exe文件,一切都会正常工作。如果我编译它并从java程序加载它,就会发生这种情况
- myJavaProgram,只需调用System.loadLibrary()来加载基本的.dll 调用我的另一个dll中包含JNI代码的方法的文件
- my_plain_dll_to_call_JNI_dll是我通过链接到我的 dll库文件只是为了测试依赖关系。它只是调用一个方法 从另一个dll调用我需要的本机代码
c:\java myJavaProgram
myJavaProgram: Java Static Method Entry.
myJavaProgram: Java Calling System.loadLibrary(my_plain_dll_to_call_JNI_DLL)
my_JNI_DLL.dll: Entering DllMain
my_JNI_DLL.dll: DLL_PROCESS_ATTACH
my_plain_dll_to_call_JNI_DLL: DLL_PROCESS_ATTACH
my_plain_dll_to_call_JNI_DLL: DLL_THREAD_ATTACH
my_plain_dll_to_call_JNI_DLL: DLL_THREAD_DETACH
my_plain_dll_to_call_JNI_DLL: DLL_PROCESS_DETACH
myJavaProgram: my_plain_dll_to_call_JNI_DLL Loaded!
myJavaProgram: Java Static Method Exit.
myJavaProgram: Entering Main().
my_plain_dll_to_call_JNI_DLL: In call_my_JNI_DLL_method
my_JNI_DLL.dll: In my_JNI_DLL_method
my_JNI_DLL.dll: Entering my_JNI_DLL_CheckEnvironmentVariables()
my_JNI_DLL.dll: Exiting my_JNI_DLL_CheckEnvironmentVariables
my_JNI_DLL.dll: Calling StartExistingNativeCode.
#
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (0xc0fb007e), pid=7500, tid=7552
#
# JRE version: 6.0_21-b06
# Java VM: Java HotSpot(TM) Client VM (17.0-b16 mixed mode, sharing windows-x86 )
# Problematic frame:
# C [KERNELBASE.dll+0x9673]
#
# An error report file with more information is saved as:
# C:\hs_err_pid7500.log
#
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
my_plain_dll_to_call_JNI_DLL: DLL_PROCESS_DETACH
my_JNI_DLL.dll: Entering DllMain
my_JNI_DLL.dll DLL_PROCESS_DETACH
更新 我已经将问题缩小到一个内存管理库,它是从我的程序使用的另一个dll链接进来的。它使用的dll是sh33w32.dll,叫做SmartHeap,我想是由一家名为Microquil的公司提供的。我的版本是3.3,当Java LoadLibrary尝试加载该dll时,它失败了。我不确定如何让java处理加载该库。这一定与Java可以访问的内存区域有关,而不是与windows允许exe访问的内存区域有关。exe与SmartHeap库没有问题,但Java不允许我使用它。有没有处理这个问题的想法或经验?我试图通过重新编译其他库来删除链接库,但代码中的正常调用失败,无法正常工作
找到其他信息 dll中无法在java中加载的函数称为MemRegisterTask。它来自Microquill的一款名为SmartHeap的产品。这是我找到的关于这个函数的文档。我认为这种内存分配是导致java无法加载它的原因 MemRegisterTask初始化SmartHeap库。在大多数平台上,您不需要调用MemRegisterTask,因为SmartHeap将在第一次调用时自动初始化
SmartHeap为每个任务或进程维护注册引用计数。每次调用MemRegisterTask时,此引用计数都会递增。如果上次调用SmartHeap发生在应用程序准备终止之前,则可以调用MemUnregisterTask终止SmartHeap。MemUnregisterTask将注册引用计数递减1-当计数为零时,SmartHeap将释放与当前任务或进程关联的任何SmartHeap分配的内存和调试状态。在我看来,这似乎是调用约定或类型大小不匹配。每个Windows C编译器都有自己的一组特性,Windows JNI头(微软VC++)的一个新版本。仔细观察警告-精度损失是一个坏迹象
例如,
\uuu int64
是MSVC特有的。您需要找出Borland C中64位整数类型的名称,并将其映射到\uu int64
,然后才能包含jni.h
任何在hs\u错误中有用的内容。。。日志文件。通常有堆栈回溯等。
指出某事
还尝试在内部运行java.exe(参数运行加载内容的测试)
调试器
从上面的跟踪可以看出加载似乎工作正常(跟踪输出表明
该dllentrypoint/dllmain已通过跟踪输出得到增强)
加载顺序如下所示: