2010-01-26 57 views
0

这是我第二次编写Java,并且从未引用过任何外部库。我在线跟踪JNI示例,并在尝试加载dll时收到UnsatisfiedLinkError。我以为我必须在尝试加载之前先创建DLL,但是我看过的所有例子都没有提及创建DLL。他们大多表示我应该先创建Java代码,然后再创建本地代码。Eclipse Java JNI,LoadLibrary链接错误

public class ClassSample1 
{ 
public native void displayHelloWorld(); 

static 
{ 
    System.loadLibrary("MyLittleJNI"); 

} 


public static void main(String[] args) 
{ 
    // TODO Auto-generated method stub 
    ClassSample1 classSample1; 
    classSample1 = new ClassSample1(); 
    classSample1.displayHelloWorld(); 

    System.out.println("Hello"); 
} 

} 

我该如何得到错误?

回答

1

您提供的示例代码假定搜索路径中存在一个名为MyLittleJNI.dll的DLL,其中包含方法displayHelloWorld。 DLL中的实际C函数名称使用定义良好的语法进行修饰。

如果在loadLibrary()中得到UnsatisfiedLinkError,那是因为JVM找不到DLL。您可以通过使用System.load(filename)方法指定DLL的完整路径名来暂时解决问题。

一旦loadloadLibrary成功,您需要确保原生函数名称正确。为此,您可以使用javah生成包含类中所有本机函数原型的头文件。

有关如何使用JNI的更多信息,请参见herehere

编辑:另外,这个问题的右边的“相关”列似乎包含几个有用的相关问题。

+0

感谢您的回复。我终于得到它的链接,但我的C DLL中的功能不显示。也许我弄错了函数签名。 – phillip 2010-01-28 18:31:58

+0

如果你的函数签名是错误的,那么从Java调用该函数应该会引发异常。如果没有异常被抛出,但是你的输出仍然没有出现,那么其他的东西是错误的。 – JesperE 2010-01-29 08:53:17

0

我尝试再次创建新项目。

所以这里是JNISample2.java文件,该文件由JAVAH -classpath产生

public class JNISample2 
{ 

    static 
    { 
     System.loadLibrary("JNISample2Dll");   
    } 

    public native void displayHelloWorld(); 

    public static void main(String[] args) 
    { 
     System.out.println("from java Hello"); 

     JNISample2 JNIsample2; 
     JNIsample2 = new JNISample2(); 
     JNIsample2.displayHelloWorld(); 
    } 

} 

这里.h文件中。 JNISample2

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

#ifndef _Included_JNISample2 
#define _Included_JNISample2 
#ifdef __cplusplus 
extern "C" { 
#endif 
/* 
* Class:  JNISample2 
* Method: displayHelloWorld 
* Signature:()V 
*/ 
JNIEXPORT void JNICALL Java_JNISample2_displayHelloWorld 
    (JNIEnv *, jobject); 

#ifdef __cplusplus 
} 
#endif 
#endif 

这是我的.h文件的dll,我创建VS2005与MFC应用程序。

// JNISample2Dll.h : main header file for the JNISample2Dll DLL 
// 

#pragma once 

#ifndef __AFXWIN_H__ 
    #error "include 'stdafx.h' before including this file for PCH" 
#endif 

#include "resource.h"  // main symbols 


#include "JNISample2.h" 


// CJNISample2DllApp 
// See JNISample2Dll.cpp for the implementation of this class 
// 

class CJNISample2DllApp : public CWinApp 
{ 
public: 
    CJNISample2DllApp(); 

// Overrides 
public: 
    virtual BOOL InitInstance(); 

    DECLARE_MESSAGE_MAP() 
}; 


JNIEXPORT void JNICALL Java_JNISample2_displayHelloWorld(JNIEnv *, jobject); 

这里是我的.cpp文件

// JNISample2Dll.cpp : Defines the initialization routines for the DLL. 
// 

#include "stdafx.h" 
#include "JNISample2Dll.h" 

#ifdef _DEBUG 
#define new DEBUG_NEW 
#endif 

// 
//TODO: If this DLL is dynamically linked against the MFC DLLs, 
//  any functions exported from this DLL which call into 
//  MFC must have the AFX_MANAGE_STATE macro added at the 
//  very beginning of the function. 
// 
//  For example: 
// 
//  extern "C" BOOL PASCAL EXPORT ExportedFunction() 
//  { 
//   AFX_MANAGE_STATE(AfxGetStaticModuleState()); 
//   // normal function body here 
//  } 
// 
//  It is very important that this macro appear in each 
//  function, prior to any calls into MFC. This means that 
//  it must appear as the first statement within the 
//  function, even before any object variable declarations 
//  as their constructors may generate calls into the MFC 
//  DLL. 
// 
//  Please see MFC Technical Notes 33 and 58 for additional 
//  details. 
// 


// CJNISample2DllApp 

BEGIN_MESSAGE_MAP(CJNISample2DllApp, CWinApp) 
END_MESSAGE_MAP() 


// CJNISample2DllApp construction 

CJNISample2DllApp::CJNISample2DllApp() 
{ 
    // TODO: add construction code here, 
    // Place all significant initialization in InitInstance 
} 


// The one and only CJNISample2DllApp object 

CJNISample2DllApp theApp; 


// CJNISample2DllApp initialization 

BOOL CJNISample2DllApp::InitInstance() 
{ 
    CWinApp::InitInstance(); 

    return TRUE; 
} 


JNIEXPORT void JNICALL Java_JNISample2_displayHelloWorld(JNIEnv *, jobject) 
{ 
    MessageBox(NULL, TEXT("In JNISample2Dll"), TEXT("DLL"), 1); 
} 

我使用命令提示符下运行后:JAVA JNISample2,它显示“从Java你好”的字符串,但怎么就不会显示消息框我把它放在.cpp DLL文件中?

+0

不要在答案中提出新问题。要么编辑你的问题,要么提出一个新的问题。 – JesperE 2010-01-29 08:52:01

+0

您的JNI入口点必须使用C-linkage编译,因此您需要在函数原型周围放置“extern”C“{...}”。 – JesperE 2010-01-29 08:54:46

+0

感谢您指出了规则和条例。是啊,我应该问新的问题.. – phillip 2010-01-29 17:46:41