2011-11-17 111 views
0

我想創建一個簡單的JNI圖層。我用Visual Studio 2008創建了一個dll(帶有DLL的Win 32控制檯應用程序項目類型作爲選項)。即時得到這個異常,當我調用本地方法:JNI UnsatisfiedLinkError

Exception occurred during event dispatching: 
java.lang.UnsatisfiedLinkError: com.tpd.vcdba.console.TaskScheduler.vcdbaTaskSch 
edulerNative.Hello()V 
     at com.tpd.vcdba.console.TaskScheduler.vcdbaTaskSchedulerNative.Hello(Na 
tive Method) 
     at com.tpd.vcdba.console.TaskScheduler.vcdbaTaskSchedulerUtil.isTaskExis 
ts(vcdbaTaskSchedulerUtil.java:118) 
     at com.tpd.vcdba.console.Dialogs.schedulerWizardPage.scheduleTaskPage.wz 
Finish(scheduleTaskPage.java:969) 
     at com.tpd.vcdba.console.wizard.vcdbaWizard.gotoFinish(vcdbaWizard.java: 
434) 
     at com.tpd.vcdba.console.wizard.wzActionPanel.actionPerformed(wzActionPa 
nel.java:163) 
     at javax.swing.AbstractButton.fireActionPerformed(Unknown Source) 

生成的頭文件是:

/* DO NOT EDIT THIS FILE - it is machine generated */ 

    #include <jni.h> 
    /* Header for class com_tpd_vcdba_console_TaskScheduler_vcdbaTaskSchedulerNative */ 

    #ifndef _Included_com_tpd_vcdba_console_TaskScheduler_ 
    vcdbaTaskSchedulerNative 
    #define _Included_com_tpd_vcdba_console_TaskScheduler_ 
    vcdbaTaskSchedulerNative 
    #ifdef __cplusplus 
    extern "C" { 
    #endif 
    /* 
    * Class:  com_tpd_vcdba_console_TaskScheduler_vcdbaTaskSchedulerNative 
    * Method: Hello 
    * Signature:()V 
    */ 
    JNIEXPORT void JNICALL Java_com_tpd_vcdba_console_TaskScheduler_vcdbaTaskSchedulerNative_Hello 
     (JNIEnv *, jobject); 

    #ifdef __cplusplus 
    } 
    #endif 
    #endif 

實現文件是:

#pragma once 
#include "com_tpd_vcdba_console_TaskScheduler_ 
vcdbaTaskSchedulerNative.h" 
#include "stdafx.h" 
#include "jni.h" 

/* 
* Class:  com_tpd_vcdba_console_TaskScheduler_vcdbaTaskScheduler_native 
* Method: Hello 
* Signature:()V 
*/ 
JNIEXPORT void JNICALL Java_com_tpd_vcdba_console_TaskScheduler_vcdbaTaskSchedulerNative_Hello 
    (JNIEnv *envs, jobject obj){ 
    printf("hello world"); 
} 

Java文件是:

package com.tpd.vcdba.console.TaskScheduler; 


import com.tpd.vcdba.console.TaskScheduler.ScheduleTask; 

public class vcdbaTaskSchedulerNative { 


    public native void Hello(); 
    private static vcdbaTaskSchedulerNative instance = null; 

    static{ 
     try{ 
      System.loadLibrary("JNITrial"); 

     } 
     catch(Exception ex){ 

     } 

    } 

    public vcdbaTaskSchedulerNative(){ 

    } 

    public static vcdbaTaskSchedulerNative getInstance(){ 
     if(instance == null){ 
      instance = new vcdbaTaskSchedulerNative(); 
     } 
     return instance; 
    } 

} 

當我我喚起本機方法「你好」,我得到了執行。我看到的另一件事是,當我在命令行中編譯時使用: 「cl -I」C:\ Program Files(x86)\ Java \ jdk1.7.0 \ include「-I」C:\ Program Files( x86)\ Java \ jdk1.7.0 \ include \ win32「-LD」C:\ Users \ administrator.RMDOM \ Documents \ Visual Studio 2008 \ Projects \ JNITrial \ JNITrial \ JNIInt.cpp「-FeJNITrial.dll」, everything works精細。

我錯過了Visual Studio設置中的東西嗎?我有選擇使用MFC作爲「在共享DLL中使用MFC」,代碼生成選項爲「多線程DLL(/ MD)」。它是一個64位的DLL。 有什麼我需要補充的嗎?

任何幫助,歡迎。 在此先感謝。

+0

你可以發佈你調用哪個引發異常的命令嗎?可能你沒有正確地將dll傳遞給java命令 –

+0

如果System.loadLibrary(「JNITrial」)失敗,catch塊不會報告異常。可以添加一個ex.printStackTrace()來檢查DLL是否被加載? – hmjd

+0

@AdityaNaidu 調用本地函數的命令是:vcdbaTaskSchedulerNative n = new vcdbaTaskSchedulerNative(); n.Hello(); – user1051577

回答

0

我想出瞭解決方案。

我的項目已使用預編譯頭選項設置,所以編譯器跳過聲明:

#include "com_tpd_vcdba_console_TaskScheduler_vcdbaTaskSchedulerNative.h" 

一旦我刪除選項,像變魔術一樣。

0

你能告訴我你使用的是32位還是64位的JVM?你的庫是640位的DLL,但在你的路徑中,我可以看到C:\ Program Files(x86)...所以也許這是問題所在。

+0

我使用的是64位JVM。我試過從x64 JDK中包含文件,但仍然收到相同的錯誤。 – user1051577