java.lang.UnsatisfiedLinkError:无法加载库' CMEngine':找不到指定的模块

时间:2016-08-26 23:53:10

标签: dll jna

因此我们通过JNA与第三方DLL集成。偶尔他们会更新他们的代码,其中包含政府要求的功能等新参数。

我得到了他们的原始C / C ++代码,他们支持那些希望在UNIX机器上运行软件的公司。他们提供的代码包括一个makefile。通常我们编译UNIX的代码,我最终得到.so文件然后我就开心地走了。它们通常为我们用于开发的窗口提供.dll等价物,然后我们的构建服务器/实时服务器使用.so,并且每个人都很高兴。然而,他们决定改变他们的项目并使用.Net,并在他们的windows .net dll&s和c代码的dll之间更改它们的参数和顺序。

所以现在我需要为Windows编译C / C ++代码并获得.dll以及为Linux编译它并获取.so文件。所以我想到了自己 - 不用担心我能做到这一点。所以我进入makefile,找到我认为正确的改变。我带来以下内容:

g++ -shared -lc -lstdc++ -o CMEngine.dll \

通常在编译linux时我们使用类似的东西:

g++ -shared -Wl,-soname,libCMEngine.so.4.73 -o /lib/libCMEngine.so -lc -lstdc++ \

换句话说,两个电话几乎完全相同。

现在对于令人沮丧的部分:我们有一个像优秀开发人员一样的JUnit测试应该测试各种方法的集成以确保一切顺利。在测试中,它到达以下行:

public CMEngine INSTANCE = (CMEngine) Native.loadLibrary("CMEngine", CMEngine.class);

同样在启动时的单元测试中,我们有以下参数:

-Djna.library.path=C:\java\api\dll\

然后我运行测试。如果我在java / api / dll / oldDll.dll文件夹中有旧的.dll,那么测试运行时会出现以下错误:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0000000180016dc0, pid=15132, tid=14804
...

但是,如果我将新的.dll放在同一个名称java / api / dll / newDll.dll中,那么我会收到错误:

java.lang.UnsatisfiedLinkError: Unable to load library 'CMEngine': The specified module could not be found.

然后看起来那个旧的dll虽然它没有工作,因为新的参数更改它至少找到了dll并加载它因此出现了seg-fault错误。然而,这也意味着它应该找到我放在完全相同位置的新dll(用完全相同的名称覆盖旧的dll)然后我找不到模块。

所以我的问题如下:  1.它无法找到模块的事实意味着我创建了一个坏的.dll - 带有dll名称的东西,但没有真正的dll,因为我的构建命令是错误的?  2.这个名字在dll中是什么意思吗?如果我命名我的DL​​L bobbysDll.dll确实对任何事情都有影响吗?  3.编译Windows时,该过程是否与Unix系统完全不同?换句话说,我的假设是我基本上从同一个编译命令中删除了.so位,然后我得到了一个可行的.dll for windows。也许我应该提一下,我使用cygwin来运行make命令。我下载了visual studio,如果有更好的方法来生成一个dll。我愿意尝试任何事情。

我很欣赏这方面的所有见解。我花了一整天的时间试图更好地理解我可能做错了什么。

1 个答案:

答案 0 :(得分:1)

  1. 它找不到模块的事实是否意味着我正在创建一个坏的.dll - 带有dll名称的东西,但没有真正的dll,因为我的构建命令是错误的?
  2. 导致“java.lang.UnsatisfiedLinkError”的原因有几个。例如

    • windows找不到dll
    • 尝试使用x64 jvm加载x86 dll或使用x86 jvm加载x64 dll
    • dll缺少其他依赖的dll(您可以尝试dependency worker
    • dll坏了

    我建议你最好编写一个使用该dll的exe程序,以确保可以正确加载dll。

    1. 这个名字是否代表dll中的任何内容?
    2. 你是说dll的名字吗?在你的情况下我不认为这很重要,因为jni使用Loadlibrary来加载dll。但如果您的exe链接到dll的导入库,则很重要。

      如果我将我的dll命名为bobbysDll.dll会对任何事情产生影响吗?

      在您的JNI代码中,您应该使用:

      System.loadLibrary("bobbysDll");
      
      1. 编译Windows时,该过程是否与Unix系统完全不同?换句话说,我的假设是我基本上从同一个编译命令中删除了.so位,然后我得到了一个可行的.dll for windows。也许我应该提一下,我正在使用cygwin来运行make命令。
      2. 我建议使用VisualStudio来构建你的dll。你需要一个def文件告诉VC要导出哪些函数。