2011-11-17 69 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