JNI Hello World不满意链接错误 [英] JNI Hello World Unsatisfied Link Error

查看:112
本文介绍了JNI Hello World不满意链接错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我第一次尝试JNI。我的最终目标是让所有任务当前在一台机器上运行,但需要运行一个简单的例子。当我尝试执行我的主程序时,我不断收到此错误。我提供了简单的Java主程序,生成的头文件和错误。

This is my first attempt at JNI. My ultimate goal is to get all tasks currently running on a machine, but need to get even a simple example running. I keep getting this error when I try to execute my main program. I have supplied my simple Java main program, the header file generated, and the error.

我不知道这个DLL可能依赖什么。它最初引用了我追踪并放入system32(msvcr90.dll)的DLL。

I do not know what this DLL could be dependent on. It was initially referencing a DLL I tracked down and placed into system32 (msvcr90.dll).

这是我用来编译C代码的命令,它生成了DLL,OBJ,LIB,EXP和清单文件。

Here is the command I used to compile the C code as well which produced the DLL, OBJ, LIB, EXP and manifest files.

cl -IC:\Program Files\Java \ _jdk1.6.0 \ include-IC:\Program Files\Java\jdk1.6.0\include \\ \\ win32-MD -LD HelloWorld.c -FeHelloWorld.dll

cl -I"C:\Program Files\Java\jdk1.6.0\include" -I"C:\Program Files\Java\jdk1.6.0\include\win32" -MD -LD HelloWorld.c -FeHelloWorld.dll

class HelloWorld {
     private native void print();
     public static void main(String[] args) {
         new HelloWorld().print();
     }
     static {
         System.load("C:\\temp\\HelloWorld.dll");
     }
 }


#include <jni.h>
 #include <stdio.h>
 #include "HelloWorld.h"

 JNIEXPORT void JNICALL 
 Java_HelloWorld_print(JNIEnv *env, jobject obj)
 {
     printf("Hello World!\n");
     return;
 }

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloWorld */

#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     HelloWorld
 * Method:    print
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_HelloWorld_print
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

java.lang.UnsatisfiedLinkError: C:\temp\HelloWorld.dll: A dynamic link library (DLL) initialization routine failed
    at java.lang.ClassLoader$NativeLibrary.load(Native Method)
    at java.lang.ClassLoader.loadLibrary0(Unknown Source)
    at java.lang.ClassLoader.loadLibrary(Unknown Source)
    at java.lang.Runtime.load0(Unknown Source)
    at java.lang.System.load(Unknown Source)
    at HelloWorld.<clinit>(HelloWorld.java:7)
Exception in thread "main" 


推荐答案

不满意的链接错误可能意味着许多事情都出错了。我会用

The Unsatisfied Link Error can mean many things went wrong. I would use

System.loadLibrary("HelloWorld");

而不是

System.load();

正如TwentyMiles建议的那样。

As TwentyMiles suggested.

此外,在调用程序时,您需要(假设您的DLL与您的类文件位于同一目录中:

Also, when invoking your program you need to (assuming your DLL is on the same directory as your class files:

java -Djava.library.path = .HelloWorld

java -Djava.library.path=. HelloWorld

这是我做的一个简单演示,调用Win32 API函数(MessageBox)

Here's a simple demo I made that calls a Win32 API function (MessageBox)

class CallApi{
    private native String showMessageBox(String msg);
    private native double getRandomDouble();

    static{
        try{
            System.loadLibrary("CallApi");
            System.out.println("Loaded CallApi");
        }catch(UnsatisfiedLinkError e){
            //nothing to do
            System.out.println("Couldn't load CallApi");
            System.out.println(e.getMessage());
        }
    }

    public static void main(String args[]){
        CallApi api = new CallApi();
        double randomNumber = api.getRandomDouble();
        String retval = api.showMessageBox("Hello from Java!\n"+
            "The native random number: "+randomNumber);
            System.out.println("The native string: "+retval);
    }
}



生成的头文件



Generated header file

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class CallApi */

#ifndef _Included_CallApi
#define _Included_CallApi
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     CallApi
 * Method:    showMessageBox
 * Signature: (Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_CallApi_showMessageBox
  (JNIEnv *, jobject, jstring);

/*
 * Class:     CallApi
 * Method:    getRandomDouble
 * Signature: ()D
 */
JNIEXPORT jdouble JNICALL Java_CallApi_getRandomDouble
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif



C DLL代码



The C DLL code

#include "CallApi.h"
#include <windows.h>
#include <stdlib.h>
#include <time.h>

#pragma comment(lib,"user32.lib")

JNIEXPORT jstring JNICALL Java_CallApi_showMessageBox
  (JNIEnv *env, jobject thisObject, jstring js)
{
    //first convert jstring to const char for use in MessageBox
    const jbyte* argvv = (*env)->GetStringUTFChars(env, js, NULL);
    char* argv =(char *) argvv;

    //Call MessageBoxA
    MessageBox(NULL, argv, "Called from Java!", MB_ICONEXCLAMATION | MB_OK);
    return js;
}

JNIEXPORT jdouble JNICALL Java_CallApi_getRandomDouble
  (JNIEnv *env, jobject thisObject)
{
    double num1;
    srand((unsigned)(time(0)));
    num1 = ((double)rand()/(double)RAND_MAX);

    return num1;
}



编译说明



我使用Visual C ++ express 2008 cl进行编译,删除-ML标志,因为当Java代码尝试调用本机代码时会导致异常:

Compile instructions

I compile with the Visual C++ express 2008 cl, removing the -ML flag since it causes an exception when the Java code tries to call the native code:

cl / I c:\Program Files \ Java \ _ddk1.6.0_10 \ include/ Ic:\ Program Files \ Java @\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -FeCallApi.dll

cl /I"c:\Program Files\Java\jdk1.6.0_10\include" /I"c:\Program Files\Java\jdk1.6.0_10\include\win32" -LD CallApi.c -FeCallApi.dll

然后,运行代码:

java -Djava.library.path =。 CallApi

java -Djava.library.path=. CallApi

这篇关于JNI Hello World不满意链接错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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