在OSGi包中加载DLL(使用JNA) [英] Load DLL (using JNA) inside an OSGi bundle

查看:94
本文介绍了在OSGi包中加载DLL(使用JNA)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

OSGi无法找到我的DLL文件,我似乎无法找出原因。

OSGi cannot find my DLL file, and I can't seem to figure out why.

目前我有DLL文件( foo .dll )在我的捆绑包的根目录下,我也尝试在 libs 目录中使用它。

Currently I have the DLL file (foo.dll) at the root of my bundle, I've also tried having it in a libs directory.

有问题的包的清单看起来像这样:

The Manifest for the bundle in question looks something like this:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: foobundle
Bundle-SymbolicName: com.foo.bar
Bundle-Version: 1.0.0
Bundle-Vendor: me
Import-Package: com.sun.jna,
 com.sun.jna.ptr,
 com.sun.jna.win32
Export-Package: com.foo.bar
Bundle-NativeCode: foo.dll;
 osname=WindowsXP;
 processor=x86

然后在我的JNA界面中执行loadLibrary(根据文档) ):

Then in my JNA interface I perform a loadLibrary (as per the documentation):

public interface MyFooInterface extends com.sun.jna.Library{
    static final MyFooInterface INSTANCE = (MyFooInterface)com.sun.jna.Native.loadLibrary("foo", MyFooInterface .class);

    // specific interface defs here...
}

然后在另一个类中我尝试使用JNA接口

Then in another class I attempt to use the JNA interface

// ...code
int var = MyFooInterface.INSTANCE.bar();
// ...more code

我通过另一个捆绑包提供JNA(导出com.sun.jna和上面导入的其他软件包),但也尝试使用此处定义的软件包打包它(在这种情况下将其添加到类路径中等)。

I have JNA supplied via another bundle (which exports com.sun.jna and the other packages imported above), but have also tried packaging it with the bundle defined here (and added it to the classpath in that case, etc.).

我也尝试过指定 Bundle-NativeCode:/foo.dll

同样感兴趣,这些是相关的OSGi属性(我使用 getprop 提取)

Also of interest, these are the relevant OSGi properties (which I pulled up using getprop)

org.osgi.framework.os.name=WindowsXP
org.osgi.framework.processor=x86

即使在所有这些之后(以及我所做的每一次试验),我总是会遇到以下错误(并且未显示堆栈跟踪):

Even after all this (and with every trial I made) I always end up with the following error (and a stack trace not shown):

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

...所以我错过了什么?

...so what am I missing?

编辑:我还应该注意到我已经测试并成功了JNA接口代码和它作为JUnit测试程序一部分的DLL。

Edit: I should also note that I've tested and had success the JNA interface code and the DLL that it talks to as part of a JUnit Test program.

编辑2 :将此代码添加到调用库的类似乎允许JNA查找库(当 Native.loadLibrary 稍后调用)。看来我应该能够根据Manifest中的Bundle-NativeCode指令来避免这个调用。很明显,一旦加载了库,Native.loadLibrary会抓取它的现有实例,但我不想依赖于这个特定于订单的策略。

Edit 2: Adding this code to the class that's calling the library seems to allow JNA to find the library (when Native.loadLibrary gets called later). It seems I should be able to avoid this call based on the Bundle-NativeCode directive in the Manifest. Clearly once the library is loaded Native.loadLibrary grabs the existing instance of it, but I'd prefer not to depend on this very order-specific tactic.

static{
    System.loadLibrary("foo");
}


推荐答案

问题是专门的JNA loadLibrary调用,这不是OSGi意识到的。当您从OSGi包调用loadLibrary时,它将使用OSGi类加载器(可识别bundle)来查找DLL的位置,在这种情况下,从包中提取它并通过System.loadLibrary()使其可加载针对特定位置调用。

The problem is the specialised JNA loadLibrary call, which is not OSGi aware. When you invoke loadLibrary from an OSGi bundle, it will use the OSGi classloader (which is bundle aware) to find where the DLL is, and in this case, extract it out from the bundle and make it loadable via the System.loadLibrary() call against a specific location.

由于这个JNA似乎是(a)不是OSGi意识到的,并且(b)超级,为什么不使用System.loadLibrary()代替?

Since this JNA seems to be (a) not OSGi aware, and (b) superflous, why not just use System.loadLibrary() instead?

如果你需要同时编写两者,那么在BundleActivator的bundle的start()方法中执行System.loadLibrary(),这将带来本机库(您可能希望确保如果无法加载,则无法在任何情况下启动捆绑包。)

If you need to write both, then perform a System.loadLibrary() in the bundle's start() method in the BundleActivator, which will bring the native library in (you probably want to ensure that if it can't be loaded, the bundle can't be started in any case).

这篇关于在OSGi包中加载DLL(使用JNA)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆