2010-01-26 66 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