JNI 不满意链接错误
我想创建一个简单的 JNI 层。我使用Visual studio 2008创建了一个dll(Win 32控制台应用程序项目类型,带有DLL作为选项)。当我调用本机方法时,我收到此异常:
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;
}
}
当我调用本机方法“Hello”时,我得到了执行。
我观察到的另一件事是,当我使用以下命令在命令行中编译时: “cl -I”C:\Program Files (x86)\Java\jdk1.7.0\include" -I"C:\Program Files (x86)\Java\jdk1.7.0\include\win32" -LD "C:\用户\管理员.RMDOM\文档\Visual Studio 2008\项目\JNITrial\JNITrial\JNIInt.cpp” -FeJNITrial.dll”, 一切正常。
我是否遗漏了 Visual Studio 设置中的某些内容?我将“使用 MFC”选项设置为“在共享 DLL 中使用 MFC”,将“代码生成”选项设置为“多线程 DLL (/MD)”。它是一个 64 位 dll。 我还需要补充什么吗?
欢迎任何帮助。 提前致谢。
I want to create a simple JNI layer. I used Visual studio 2008 to create a dll (Win 32 Console Application project type with DLL as the option). Im getting this exception when I invoke the native method:
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)
The header file generated is :
/* 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
The implementation file is:
#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");
}
The java file is:
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;
}
}
When I invoke the native method "Hello" i get the execption.
Another thing I observed is that when I compile in command line using:
“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 fine.
Am I missing out something in Visual Studio Settings? I have option Use of MFC as "Use MFC in a Shared DLL", Code generation option as "Multi-threaded DLL (/MD)". Its a 64 bit dll.
Is there something else that I need to add?
Any help is welcome.
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
你能告诉我你使用的是哪种 JVM,32 位还是 64 位吗?您的库是 640 位 dll,但在您的路径中我可以看到 C:\Program Files (x86)...所以也许这就是问题所在。
Could you tell me what kind of JVM are you using, 32 or 64-bit? Your library is 640bit dll, but in your path I can see C:\Program Files (x86)... so maybe this is the problem.
我想出了解决办法。
我的项目使用了预编译头选项集,因此编译器跳过了语句:
一旦我删除了该选项,它就会像魔术一样工作。
I figured out the solution.
My project had use precompiled headers option set, so the compiler was skipping the statement:
Once I removed that option it worked like magic.