因此我们通过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中是什么意思吗?如果我命名我的DLL bobbysDll.dll确实对任何事情都有影响吗? 3.编译Windows时,该过程是否与Unix系统完全不同?换句话说,我的假设是我基本上从同一个编译命令中删除了.so位,然后我得到了一个可行的.dll for windows。也许我应该提一下,我使用cygwin来运行make命令。我下载了visual studio,如果有更好的方法来生成一个dll。我愿意尝试任何事情。
我很欣赏这方面的所有见解。我花了一整天的时间试图更好地理解我可能做错了什么。
答案 0 :(得分:1)
导致“java.lang.UnsatisfiedLinkError”的原因有几个。例如
我建议你最好编写一个使用该dll的exe程序,以确保可以正确加载dll。
如果我将我的dll命名为bobbysDll.dll会对任何事情产生影响吗?
在您的JNI代码中,您应该使用:
System.loadLibrary("bobbysDll");
我建议使用VisualStudio来构建你的dll。你需要一个def文件告诉VC要导出哪些函数。