Eclipse Java JNI,LoadLibrary链接错误

时间:2010-01-26 23:58:51

标签: eclipse java-native-interface

这是我第二次编写Java并且之前从不引用任何外部库。我在线关注JNI示例,在尝试加载dll时遇到UnsatisfiedLinkError。我认为我必须在尝试加载之前先创建DLL,但我看过的所有示例都没有提到创建DLL。他们中的大多数人都说我应该首先创建Java代码,然后再创建本机代码。

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");
 }

}

如何驾驭错误?

2 个答案:

答案 0 :(得分:1)

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

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

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

有关如何使用JNI的详细信息,请参阅herehere

编辑:此外,此问题右侧的“相关”列似乎包含一些有用的相关问题。

答案 1 :(得分:0)

我尝试再次创建新项目。

所以这里是JNISample2.java文件

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();
    }

}

这里是由javah -classpath生成的.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,我使用MFC应用程序创建VS2005。

// 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,它显示字符串“from java Hello”,但是为什么它不显示我放在.cpp DLL文件中的messagebox?