我的dll代码从一个exe文件中工作,但是无法从Java loadLibrary加载

我创建了一个C模块来构建一个共享库文件,然后使用JNI从Java中调用它。

我有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分配内存和调试状态。

在hs_err …日志文件中有用的任何东西。通常有一个堆栈回溯等
指出一些东西

还试图运行java.exe(参数运行测试加载的东西)里面
调试器?

从跟踪上面可以看到加载似乎工作正常(跟踪输出建议
那个dllentrypoint / dllmain已经被你增加了跟踪输出)。

加载顺序如下:

>依赖负载的dll
> load dll本身
>调用dllentrypoint / dllmain w / process attach

所以这已经是加载DLL了。

您是否检查过您是否使用Windows中的调试/释放运行时间?调试可能与发布冲突 – Java发布,您的示例exe可能与您的dll版本相同。

相关文章

Windows注册表操作基础代码 Windows下对注册表进行操作使用的...
黑客常用WinAPI函数整理之前的博客写了很多关于Windows编程的...
一个简单的Windows Socket可复用框架说起网络编程,无非是建...
Windows文件操作基础代码 Windows下对文件进行操作使用的一段...
Winpcap基础代码 使用Winpcap进行网络数据的截获和发送都需要...
使用vbs脚本进行批量编码转换 最近需要使用SourceInsight查看...