我创建了一个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版本相同。

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

  1. android – Carousel中的ArrayIndexOutOfBoundsException – MessageQueue回调和handleReceiveCallback中的异常

    我在我的应用程序中使用轮播.对于拥有Android4.2.2且仅在横向模式下的用户,他们报告此问题:我无法在这里找到问题所在.解决方法看起来您将视图存储在数组中.旋转设备时,将重置此阵列并删除所有视图.当数组适配器尝试获取其位置时,因为该数组为空,所以它返回-1.尝试处理旋转事件并确保重新填充数组.我没有看到一些代码就无法回答,但它看起来像是清空或设置为null的视图数组/列表.

  2. android – JNI:如何获得jbyteArray大小

    背景我正在使用JNI中的字节数组.而且我无法获得jbyteArray的长度.我正在Windows7中的eclipse中编写代码.Java代码:JNI代码:在JNI中,我有一个结构,它有两个成员无符号长度和无符号字符数据[1]现在我的JNI函数得到参数jbyteArrayjpSeed我想得到jpSeed的长度并将其设置为struct的length成员.问题1:如何在JNI中获得jpSeed的长度?问题2:此代码是否正常bd.data[1]=jbyteArray;?

  3. Android JNI中的高精度计时器

    我正在尝试描述我的JNI应用程序.是否有类似“自启动后获取刻度”的东西,我可以用来衡量功能和/或系统?

  4. Android NDK中的JNIEXPORT和JNICALL

    ){但是,AndroidNDK示例不使用它们.我从Oracle读了一些文档,但我仍然感到困惑.使用AndroidNDK时是否必须使用它们?问的原因之一–在eclipseCDT中突出显示的那些宏中断语法:)解决方法基本上是一个Windows问题,如果你看看oracleJavajdk附带的文件jni_md_win32.h这是宏定义:在头文件jni_md_linux.h中,这些宏是空的.所以我想,只要您不希望在使用oracleJVM的Windows中执行本机代码,就可以删除这些宏.

  5. android – JNI在应用程序中检测到错误

    我在wordpress中使用API来获取我拥有的标题数量.我的代码适用于除5.x之外的所有Android版本.当我在我的应用程序中推送一个帖子时,很遗憾地关闭了.我不知道Android5版本有什么问题.有谁知道解决方案是什么?

  6. android-studio – 无法使用Android Studio从JNI打印日志消息

    我得到的错误:error:undefinedreferenceto‘__android_log_print’我已将此行添加到我的.cpp文件中:我尝试过两种方法:__android_log_print和__android_log_write我还在我的Android.mk文件(我手动编译)中链接了日志库.LOCAL_LDLIBS:=–llog我也尝试了几种我认为的替代品:这是我的Android.mk

  7. Android JNI C/C++执行代码的当前工作目录是什么?

    在Android中,如果调用使用NDK创建的C/C++共享库并且它加载文件的当前工作目录是什么?谢谢解决方法当前目录是“/”,而不是应用程序目录:要获取应用程序目录,您需要使用对Java代码的JNI调用,而Java代码又从Context获取android应用程序目录.

  8. Android Studio 2.2原生开发迁移问题

    在切换到AS2.2之前,我有以下结构来实现我的C在这种情况下一切都很好.但是,升级到AS2.2后,我无法构建任何apk并始终收到以下错误:ExecutionFailedfortask':app:transformNative_libsWithStripDebugSymbolForDebugjava.lang.NullPointerException(noerrormessage)有人知道为什么吗?

  9. 在Android中使用C构建NDK的问题

    目前我正在使用AndroidNDK和JNI.我正在尝试使用NDK构建C代码.但是我遇到了以下错误:有人可以帮帮我吗?解决方法我刚遇到同样的问题.似乎STL默认情况下不会自动包含在NDK项目中.这也意味着iostream,fstream,string等不能马上使用.要启用它们,您需要修改Application.mk文件.如果您没有,那么只需创建一个新的空白目录.添加行:另外,还要记得包括使用namespacestd;或等效的,以及通常的#include等等

  10. “您的APP_BUILD_SCRIPT指向一个未知文件:./ jni / Android.mk”

    我搜索了所有网(我认为).什么曾经说过我试过但没有运气不工作我在cygwin和windows下测试它这是我的项目文件/目录:这是我的ndkNDK_LOG=1输出:和我的Android.mk简单就像在文档中说的那样,但仍然无法正常工作..为什么它不能正常运作的原因是什么?解决方法显然,你的Android.mk文件位于错误的位置,因为它的当前位置是:并且您的构建脚本期望它在您必须更改脚本或复制/移动文件.

随机推荐

  1. static – 在页面之间共享数据的最佳实践

    我想知道在UWP的页面之间发送像’selectedItem’等变量的最佳做法是什么?创建一个每个页面都知道的静态全局变量类是一个好主意吗?

  2. .net – 为Windows窗体控件提供百分比宽度/高度

    WindowsForm开发的新手,但在Web开发方面经验丰富.有没有办法为Windows窗体控件指定百分比宽度/高度,以便在用户调整窗口大小时扩展/缩小?当窗口调整大小时,可以编写代码来改变控件的宽度/高度,但我希望有更好的方法,比如在HTML/CSS中.在那儿?

  3. 使用Windows Azure查询表存储数据

    我需要使用特定帐户吗?>将应用程序部署到Azure服务后,如何查询数据?GoogleAppEngine有一个数据查看器/查询工具,Azure有类似的东西吗?>您可以看到的sqlExpressintance仅在开发结构中,并且一旦您表示没有等效,所以请小心使用它.>您可以尝试使用Linqpad查询表格.看看JamieThomson的thispost.

  4. windows – SetupDiGetClassDevs是否与文档中的设备实例ID一起使用?

    有没有更好的方法可以使用DBT_DEVICEARRIVAL事件中的数据获取设备的更多信息?您似乎必须指定DIGCF_ALLCLASSES标志以查找与给定设备实例ID匹配的所有类,或者指定ClassGuid并使用DIGCF_DEFAULT标志.这对我有用:带输出:

  5. Windows Live ID是OpenID提供商吗?

    不,WindowsLiveID不是OpenID提供商.他们使用专有协议.自从他们的“测试版”期结束以来,他们从未宣布计划继续它.

  6. 如果我在代码中进行了更改,是否需要重新安装Windows服务?

    我写了一个Windows服务并安装它.现在我对代码进行了一些更改并重新构建了解决方案.我还应该重新安装服务吗?不,只需停止它,替换文件,然后重新启动它.

  7. 带有双引号的字符串回显使用Windows批处理输出文件

    我正在尝试使用Windows批处理文件重写配置文件.我循环遍历文件的行并查找我想要用指定的新行替换的行.我有一个’函数’将行写入文件问题是%Text%是一个嵌入双引号的字符串.然后失败了.可能还有其他角色也会导致失败.如何才能使用配置文件中的所有文本?尝试将所有“在文本中替换为^”.^是转义字符,因此“将被视为常规字符你可以尝试以下方法:其他可能导致错误的字符是:

  8. .net – 将控制台应用程序转换为服务?

    我正在寻找不同的优势/劣势,将我们长期使用的控制台应用程序转换为Windows服务.我们为ActiveMQ使用了一个叫做java服务包装器的东西,我相信人们告诉我你可以用它包装任何东西.这并不是说你应该用它包装任何东西;我们遇到了这个问题.控制台应用程序是一个.NET控制台应用程序,默认情况下会将大量信息记录到控制台,尽管这是可配置的.任何推荐?我们应该在VisualStudio中将其重建为服务吗?我使用“-install”/“-uninstall”开关执行此操作.例如,seehere.

  9. windows – 捕获外部程序的STDOUT和STDERR *同时*它正在执行(Ruby)

    哦,我在Windows上:-(实际上,它比我想象的要简单,这看起来很完美:…是的,它适用于Windows!

  10. windows – 当我试图批量打印变量时,为什么我得到“Echo is on”

    我想要执行一个简单的批处理文件脚本:当我在XP中运行时,它给了我预期的输出,但是当我在Vista或Windows7中运行它时,我在尝试打印值时得到“EchoisOn”.以下是程序的输出:摆脱集合表达式中的空格.等号(=)的两侧可以并且应该没有空格BTW:我通常在@echo关闭的情况下启动所有批处理文件,并以@echo结束它们,所以我可以避免将代码与批处理文件的输出混合.它只是使您的批处理文件输出更好,更清洁.

返回
顶部