我有2个环境,Windows和Unix,我有一个C可执行程序和一个Java程序,我只是为每个环境重新编译。
>当我在Unix中编译我的tester.exe程序并使用方法运行它
从我的图书馆(.so)它工作正常。
>当我在Unix中编译我的Java程序并加载我的库(.so)
Java的loadLibrary,它工作正常。
>当我在Windows中编译我的tester.exe程序并运行它
方法从我的库(.dll)它工作正常。就像unix一样
版。
>当我在Windows中编译我的Java程序并使用Java的loadLibrary加载我的库(.dll)时,它将失败。它说尝试访问
无效地址。
我不知道为什么在Windows中运行Java loadLibrary时它不会起作用,但是在其他地方使用相同的代码可以工作。如果我延迟加载我的库使用的依赖DLL,那么我的库加载在Java中但不起作用。我知道有特定的代码导致Java加载我的库的问题,但我不知道为什么我的C exe没有问题与相同的方法和库。
我的dll有一个暴露的方法,它调用了一些现有库中的4种方法。如果我评论这4种方法,那么我的dll加载Java可以罚款。我知道这是从图书馆我的dll链接到这些方法。 Java看到依赖库有什么不同吗?我已经尝试加载依赖库,但我加载的一个dll文件会导致递归错误,堆栈溢出。
任何人知道一个方法围绕一个DLL,导致堆栈从递归错误溢出?我需要其中的方法,但是我无法使用java loadLibrary加载它。
以下是有关所涉及文件和实际错误信息的更多详细信息。
我添加了一个DllMain到我的初始dll文件,只是为了看看什么负载和什么时候。如果我将该程序(my_plain_dll_to_call_JNI_DLL)编译为一个exe文件,一切正常。如果我编译它,并从我的java程序加载它发生。
> myJavaProgram,只需调用System.loadLibrary()来加载基本的.dll
在我的另一个dll中调用包含JNI代码的方法的文件。
> my_plain_dll_to_call_JNI_DLL是通过将其链接到我创建的dll
dll库文件只是为了测试依赖。它只是调用一个方法
从其他dll调用我需要的本机代码。
> my_JNI_DLL.ll是一个与现有C编程链接的dll文件
我需要从JNI访问的库。它包含直接调用
现有的源代码库中的方法。
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不允许我使用它。处理这个的任何想法或经验?我已经尝试通过重新编译其他库来删除链接库,但是代码中的常规调用失败,通常工作。
找到附加信息
在java中无法加载的dll中的函数称为MemRegisterTask。来自Microquill的SmartHeap产品。以下是我发现的有关此功能的文档。我认为这个内存分配是什么导致java无法加载它。
MemRegisterTask初始化SmartHeap库。在大多数平台上,您不需要调用MemRegisterTask,因为当您进行第一个调用时,SmartHeap将自动初始化。
SmartHeap维护每个任务或进程的注册引用计数。每次调用MemRegisterTask时,这个引用计数将递增。如果您的SmartHeap上次调用发生在应用程序准备好终止之前,可以调用MemUnregisterTask来终止SmartHeap。 MemUnregisterTask将注册引用计数递减1 – 当计数为零时,SmartHeap将释放与当前任务或进程相关联的任何SmartHeap分配内存和调试状态。