Eclipse插件,调用C DLL

Eclipse plugin, call C++ dll

本文关键字:DLL 调用 插件 Eclipse      更新时间:2023-10-16

我有一个自己的构建日食插件,我需要调用c dll。

我试图通过两个步骤进行操作:1.通过Java主题拨打C DLL,在我的Eclipse-Plugin之外2.尝试将其输入我的插件(这是问题所在的地方)

  1. 外日食插件。

主Java-Code Helloworld.java。

class HelloWorld {
    //public native void print();  //native method
    public native String print(String msg);  //native method
    static   //static initializer code
    {
        System.loadLibrary("CLibHelloWorld");
    } 
    public static void main(String[] args)
    {
    //HelloWorld hw = new HelloWorld();
        //hw.print();
    String result = new HelloWorld().print("Hello from Java");
    System.out.println("In Java, the returned string is: " + result);
    }
}

通过命令编译:" c: program文件 java jdk1.6.0_34 bin javac" helloworld.java

然后,我为C dll做了一个h-file helloworld.h,

" c: program文件 java jdk1.6.0_34 bin javah" helloworld

H文件看起来像这样:

#include <jni.h>
/* Header for class HelloWorld */
#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     HelloWorld
 * Method:    print
 * Signature: (Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_HelloWorld_print
  (JNIEnv *, jobject, jstring);
#ifdef __cplusplus
}
#endif
#endif

现在C dll clibhellowerld.cpp:

#include "HelloWorld.h"
#include "jni.h"
#include "stdafx.h"
#include "tchar.h"
#import "..ManagedVBDLLbinDebugManagedVBDLL.tlb" raw_interfaces_only
using namespace ManagedVBDLL;
JNIEXPORT jstring JNICALL Java_HelloWorld_print(JNIEnv *env, jobject thisObj, jstring inJNIStr) {
   jboolean blnIsCopy;
   const char *inCStr;
   char outCStr [128] = "string from C++";
   inCStr = env->GetStringUTFChars(inJNIStr, &blnIsCopy);
   if (NULL == inCStr) return NULL;
   printf("In C, the received string is: %sn", inCStr);
   env->ReleaseStringUTFChars(inJNIStr, inCStr);  
   return env->NewStringUTF(outCStr);
}

构建DLL

当我运行Java Mainprogram ...都可以正常工作!

  1. 尝试将其放入我的Eclipse插件(这是问题所在的地方)

我做了一个应该称为C DLL的课程:

package org.eclipse.ui.examples.recipeeditor.support;
import org.eclipse.jface.dialogs.MessageDialog;
public class HelloWorld {
    public native String print(String msg);  //native method
    static   //static initializer code
    {
        try {
            System.loadLibrary("CLibHelloWorld"); //$NON-NLS-1$
        } catch (Exception e) {
            e.printStackTrace();
            MessageDialog.openInformation(null, "HelloWorld", "HelloWorld Catch: " + e.getMessage());
        }
    } 
}

这样称呼:

HelloWorld hw = new HelloWorld();
result = hw.print("Hi from Eclipse");

然后我在hw.print上得到此错误(DLL的负载已完成):

java.lang.unsatisfiedlinkerror:org.eclipse.ui.examples.recipeeditor.support.helloworld.print(ljava/lang/lang/string;)ljava/lang/lang/lang/string;

一个长篇小说,但是我该如何解决?

谢谢。

system.system.loadlibrary仅在LD_LIBRARY_PATH(Linux)或路径(Windows)中可用时加载库。您还需要尊重正确的名称。不确定在Windows中,但是在Linux中,如果您像以前一样加载CLibHelloWorld,则DLL应称为libCLibHelloWorld.so。我想有一个系统。GetNativeMethodname或类似的东西,因此您可以找到它。

无论如何,这并不是我加载DLL的预先依据的方式,因为您取决于许多环境设置。相反,您可以使用System.load (dll_full_path)加载DLL。它具有相同的效果,但是您有更多的控制权。

但是,如果您使用此方法成功地加载了dll,并且在尝试调用本机方法时会在上述错误上遇到错误,请查看DLL依赖项。您应该首先加载依赖项,然后您要调用的lib。

示例,如果要加载dll1,这取决于dll2(取决于dll3),则应执行:

System.load(dll3_path);
System.load(dll2_path);
System.load(dll1_path);

本机代码中的方法名称必须对应于Java类的 class和package 名称。由于您的helloworld-class从默认包装更改为org.eclipse.ui.examples.recipeeditor.support,您必须更改方法名称。

只是在您的新课程中重新运行Javah,以获取正确的标题文件。

顺便说一句,如果您使用

之类的内容正确定义OSGI-Bundle中的DLL,则不需要设置单独的库路径。
Bundle-NativeCode: mydll.dll ; osname=win32 ; processor=x86

并将dll包括在插件的根目录中。