Eclipse plugin, C ++ dll call

I have my own built-in Eclipse plugin where I need to call the C ++ dll.

I tried to do this in two steps: 1. outside my Eclipse plugin through the main Java program that calls the C ++ dll 2. try to connect it to my plugin (this is the problem)

  • outside of the Eclipse plugin.

The main Java code is 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); } } 

Compiled by the command: "C: \ Program Files \ Java \ jdk1.6.0_34 \ bin \ javac" HelloWorld.java

Then I made h the HelloWorld.h file for the C ++ dll using:

"C: \ Program Files \ Java \ jdk1.6.0_34 \ bin \ javah" HelloWorld

h file looks like this:

 #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 

Now C ++ dll CLibHelloWorld.cpp:

 #include "HelloWorld.h" #include "jni.h" #include "stdafx.h" #include "tchar.h" #import "..\ManagedVBDLL\bin\Debug\ManagedVBDLL.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: %s\n", inCStr); env->ReleaseStringUTFChars(inJNIStr, inCStr); return env->NewStringUTF(outCStr); } 

Build dll

When I run the main java program ... everything works fine!

  • try connecting it to my Eclipse plugin (this is the problem)

I created a class that should call the 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()); } } } 

and name it as follows:

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

Then I get this error on hw.print (DLL loading completed):

java.lang.UnsatisfiedLinkError: org.eclipse.ui.examples.recipeeditor.support.HelloWorld.print (Ljava / lang / String;) Ljava / lang / String;

A long story, but how can I solve it?

Thanks.

+4
source share
2 answers

System.loadLibrary loads a library only if it is available in LD_LIBRARY_PATH (Linux) or PATH (Windows). You also need to respect the correct name. Not sure about windows, but on Linux, if you load CLibHelloWorld , just like you, your DLL should be called libCLibHelloWorld.so . I assume there is System.getNativeMethodName or something like that so you can find it.

In any case, this is not my preferred way to load the DLL, since you depend on a lot of environment settings. Instead, you can use System.load (dll_full_path) to load your DLL. It has the same effect, but you have more control.

If you successfully load your DLL using this method and continue to receive the error above when trying to call your own method, look at the DLL dependencies. You must first load the dependencies and then call lib.

For example, if you want to load dll1, which depends on dll2, which depends on dll3, you should do:

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

The method name in the native code must correspond to the class and package name of the java class. Since your HelloWorld class has been changed from the default package to org.eclipse.ui.examples.recipeeditor.support, you will have to change the method name.

Just run javah with the new class to get the correct header file.

Btw, there is no need to set a separate library path if you correctly define the dll in your OSGI set using something like

 Bundle-NativeCode: mydll.dll ; osname=win32 ; processor=x86 

and include the DLL in your plugin root directory.

0
source

Source: https://habr.com/ru/post/1445212/


All Articles