1

RCP アプリケーション (RCP-APP と呼ばれます) があります。メディア プレーヤー API (.jar ファイル) と、メディア プレーヤー API が JNA 経由でアクセスする C ライブラリ (dll) のフォルダーをラップする新しいプラグイン (プラグイン A と呼ばれます) を作成しました。次に、プラグイン A に依存するメディア プレーヤー アプリケーションを含む別のプラグイン (プラグイン B と呼ばれます) を作成しました。

プラグイン B をアクティブにすると、次のエラー メッセージが表示され、プラグイン B が探しているメディア プレーヤーの .dll を見つけられないことが通知されます。

エントリー org.eclipse.jface 4 2 2009-06-22 10:05:22.475
!MESSAGE プラグイン「org.eclipse.jface」からコードを呼び出すときに問題が発生しました。
!スタック 0
java.lang.UnsatisfiedLinkError: ライブラリ 'libvlc' を読み込めません: 指定されたモジュールが見つかりませんでした。

    com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:114) で
    com.sun.jna.NativeLibrary.getInstance (NativeLibrary.java:157) で
    com.sun.jna.Library$Handler.(Library.java:123) で
    com.sun.jna.Native.loadLibrary(Native.java:260) で
    com.sun.jna.Native.loadLibrary(Native.java:246) で
    org.videolan.jvlc.internal.LibVlc.(LibVlc.java:41) で
    org.videolan.jvlc.JVLC.(JVLC.java:45) で
    com.bah.gs.arts.jekyll.plugins.videolog.VideoLogDisplay.displayStream(VideoLogDisplay.java:32) で
    com.bah.gs.arts.jekyll.core.extensionpoints.DisplayStreamFactory.getDisplayStreams (DisplayStreamFactory.java:57) で
    com.bah.gs.arts.jekyll.core.views.medialist.MediaListView$1.doubleClick(MediaListView.java:91) で
    org.eclipse.jface.viewers.StructuredViewer$1.run(StructuredViewer.java:799) で
    org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:37) で
    org.eclipse.core.runtime.Platform.run (Platform.java:880) で
    org.eclipse.ui.internal.JFaceUtil$1.run(JFaceUtil.java:48) で
    org.eclipse.jface.util.SafeRunnable.run(SafeRunnable.java:175) で
    org.eclipse.jface.viewers.StructuredViewer.fireDoubleClick (StructuredViewer.java:797) で
    org.eclipse.jface.viewers.AbstractTreeViewer.handleDoubleSelect (AbstractTreeViewer.java:1419) で
    org.eclipse.jface.viewers.StructuredViewer$4.widgetDefaultSelected(StructuredViewer.java:1173) で
    org.eclipse.jface.util.OpenStrategy.fireDefaultSelectionEvent (OpenStrategy.java:237) で
    org.eclipse.jface.util.OpenStrategy.access$0(OpenStrategy.java:234) で
    org.eclipse.jface.util.OpenStrategy$1.handleEvent(OpenStrategy.java:295) で
    org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) で
    org.eclipse.swt.widgets.Widget.sendEvent (Widget.java:1003) で
    org.eclipse.swt.widgets.Display.runDeferredEvents (Display.java:3823) で
    org.eclipse.swt.widgets.Display.readAndDispatch (Display.java:3422) で
    org.eclipse.ui.internal.Workbench.runEventLoop (Workbench.java:2384) で
    org.eclipse.ui.internal.Workbench.runUI (Workbench.java:2348) で
    org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2200) で
    org.eclipse.ui.internal.Workbench$5.run(Workbench.java:495) で
    org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:288)で
    org.eclipse.ui.internal.Workbench.createAndRunWorkbench (Workbench.java:490) で
    org.eclipse.ui.PlatformUI.createAndRunWorkbench (PlatformUI.java:149) で
    com.bah.gs.arts.jekyll.core.Application.start(Application.java:20) で
    org.eclipse.equinox.internal.app.EclipseAppHandle.run (EclipseAppHandle.java:193) で
    org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication (EclipseAppLauncher.java:110) で
    org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79) で
    org.eclipse.core.runtime.adaptor.EclipseStarter.run (EclipseStarter.java:386) で
    org.eclipse.core.runtime.adaptor.EclipseStarter.run (EclipseStarter.java:179) で
    sun.reflect.NativeMethodAccessorImpl.invoke0(ネイティブメソッド)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) で
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) で
    java.lang.reflect.Method.invoke(Method.java:597) で
    org.eclipse.equinox.launcher.Main.invokeFramework (Main.java:549) で
    org.eclipse.equinox.launcher.Main.basicRun (Main.java:504) で
    org.eclipse.equinox.launcher.Main.run (Main.java:1236) で
    org.eclipse.equinox.launcher.Main.main (Main.java:1212) で

.dll がプラグイン A の特定のフォルダにあることをプラグイン B (または RCP-APP) に通知するにはどうすればよいですか?

APIは、環境PATH変数を介して.dllを見つけることを期待しているようです。

「plugin A/Folder-Name」を本質的に伝えるにはどうすればよいですか?

ご協力ありがとうございます。

4

3 に答える 3

1

Bundleplugin-a/folder 内の .DLL ファイルにアクセスするには、プラグイン A のインスタンスにアクセスする必要があります。1 つの方法はActivator、少なくともクラスPlugin(" PluginA") を拡張する for プラグイン A を実装することです。

この呼び出しPluginA.getDefault().getBundle().getEntry("folder/some.dll")は、.DLL ファイルへの URL を返します。

私見では、.DLL ファイルに直接アクセスするすべてのコードをプラグイン A に配置することをお勧めします。この方法では、プラグインの内部ファイル構造をユーザーに公開する必要がありません。

于 2009-06-22T14:54:38.013 に答える
1

おそらく、プラグインのフラグメントを見たいと思うでしょう。これにより、一般向けの Java API を (プラットフォーム固有の) dll/so ファイルから切り離すメカニズムが提供されます。

SWT のパッケージングは​​、この種の問題を検討するのに適した場所です。

于 2009-06-26T21:28:37.230 に答える
0

「バイナリ」プラグインを構築し、その dll をそのサブフォルダー bin/ に配置してから、マニフェストで * アクティベーター + シングルトン プロパティを追加することを確認します。* 「ビルド」、「ランタイム ビルド」セクションで bin/ をチェックします。

バイナリ プラグインを含む機能で、「インストール後にプラグイン アーカイブを展開する」にチェックを入れてください。

バイナリ プラグインのアクティベーターに、次のようなものを追加します。

public enum Tool {reach, ctl, ltl};
private static URI toolUri [] = new URI [3];

public static URI getProgramURI(Tool tool) throws IOException {
    if (toolUri[tool.ordinal()] == null) {
        String relativePath = "bin/its-"+ tool.toString() ;
        URL toolff = getDefault().getBundle().getResource(relativePath);
        if (toolff == null) {
            log.severe("unable to find an executable [" + tool + "] in path " + relativePath);
            Enumeration<URL> e = getDefault().getBundle().findEntries("bin/", "*", true);
            log.fine("Lising URL available in bin/");
            while (e.hasMoreElements()) {
                log.finer(e.nextElement().toString());
            }
            throw new IOException("unable to find the tool binary");
        }
        URL tmpURL = FileLocator.toFileURL(toolff);

        // use of the multi-argument constructor for URI in order to escape appropriately illegal characters
        URI uri;
        try {
            uri = new URI(tmpURL.getProtocol(), tmpURL.getPath(), null);
        } catch (URISyntaxException e) {
            throw new IOException("Could not create a URI to access the binary tool :", e);
        }
        toolUri[tool.ordinal()] = uri;
        log.fine("Location of the binary : " + toolUri);

        File crocExec = new File(uri);
        if (!crocExec.setExecutable(true)) {
            log.severe("unable to make the command-line tool executable [" + toolUri + "]");
            throw new IOException("unable to make the command-line tool executable");
        }       

    }
    return toolUri[tool.ordinal()];
}

私のいくつかのコードからコピーして貼り付けたので、申し訳ありませんが、DLL の例と完全には一致しません。制限されたリストから実行可能パスを取得していました (enum ツールを参照)。最後のステップ (ファイルに +x フラグを設定する) は、おそらくあなたのケースでは役に立ちません。一方、いくつかの例外処理コードとキャッシュを無料で入手できます:)そして、かなり徹底的にテストされています。

それはあなたがやろうとしている仕事をし、バイナリへのURLを下流のプラグインに渡します。

于 2015-07-03T16:03:42.713 に答える