Java JNA -> C++ -> .NET 库必须在 System32 中

Java JNA -> C++ -> .NET Library Must Be In System32

本文关键字:gt System32 C++ JNA Java NET      更新时间:2023-10-16

我让Java通过JNA调用c++/CLR库。当附加到c# DLL(使用#using<myc#>)时,c# DLL 必须在System32中,否则JVM会崩溃(原因很明显)。

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  Internal Error (os_windows_x86.cpp:149), pid=9932, tid=7464
#  guarantee(result == EXCEPTION_CONTINUE_EXECUTION) failed: Unexpected result from topLevelExceptionFilter
#
# JRE version: 6.0_26-b03
# Java VM: Java HotSpot(TM) 64-Bit Server VM (20.1-b02 mixed mode windows-amd64 compressed oops)
# An error report file with more information is saved as:
# (log dir)
#
# 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.
#

听起来像是路径问题,对吗?有趣的是:

如此:

C:比;C:workspacebinplugins64; C: WindowsSystem32

这并不:

C:比;C:workspacebinplugins64

是,库驻留在c:workspacebinplugins64

注意,如果system32包含在path中,它会找到我的库,所以它会正确地挖掘path目录(或看起来如此),但是如果我直接将它放在我的DLL在我的工作空间中的位置,它就无法运行它。我怀疑这是因为它是一个。net DLL(注册到GAC并不能修复它,尽管如果它做了我不能),我有一种感觉,这只是一个普通的库查找问题。

我错过了Java可能对我的库搜索路径做的一些事情吗?我不能保证我有能力写System32(更不用说我需要做一些自动化的事情,并希望远离操作系统目录)。

编辑1:

如果我的c# DLL不是在C: windows System32中,而是在C:workspacebinplugins64中,那么这将不起作用,所以采取我愚蠢的假设,我可以将System32排除在方程之外。

C:比;C:workspacebinplugins64; C: WindowsSystem32

将DLL移回c:windowssystem32允许它工作。

编辑2:

如果它有任何区别,它根本不会运行如果它是从Eclipse而不是命令行运行…System.getenv(" path ")从Eclipse中运行显示了我的完整路径,从c++/CLR DLL中删除c# DLL允许它运行。

所以它完全是。net DLL,从命令行运行Java。net DLL必须在System32中,并且根本不会在Eclipse中运行。

如果你从c++/CLR DLL中删除。net DLL,它可以随时随地运行。

编辑3:

在GAC注册时似乎工作得很好(感觉不好,我发誓它以前不工作),并与此问题相关:

从Java调用。net程序集:JVM崩溃

现在看看我是否可以让AssemblyResolve在c++/CLR上工作,这是非常困难的,因为它是一个库。

你的。net库显然有依赖关系。我当然期望的一个依赖项是mscoree.dll,它位于System32中。我也会仔细检查是否有CPU限制在您的DLL或它的任何依赖关系(见"64位服务器")。

好吧,注册GAC修复它,所以我写了一个非常简单的程序,注册dll与GAC (gacutil.exe是不可重新分发的)。

我将把它包含在Java应用程序中,它可以在运行时注册库。

编辑

我无法使用GAC(我从这里插入非GAC注册的库,为什么要处理复杂的动态绑定),所以我使用Assembly Binder Log Entry Viewer来显示它在哪里搜索库,我已经将JRE打包到我的应用程序中,所以我可以轻松地在运行时将。net dll复制到java目录。

一个有点糟糕的实现,但它可以工作。

我希望这篇文章能给别人省去很多麻烦。