This my second time coding Java and never referencing any external library before. I follow the JNI examples online and I get UnsatisfiedLinkError when trying to load the dll. I thought that I have to create DLL first before trying to load, but all the examples I've looked they don't mention about creating DLL. Most of them stating that I should create Java code first then native code.
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();
cla开发者_如何学运维ssSample1.displayHelloWorld();
System.out.println("Hello");
}
}
How can I get ride of the error?
The sample code you provide assumes that there is a DLL in the search path called MyLittleJNI.dll
, containing a method displayHelloWorld
. The actual C function name in the DLL is decorated using a well defined syntax.
If you get an UnsatisfiedLinkError
in loadLibrary(), it is because the JVM cannot find the DLL. You can duck the issue temporarily by specifying the full pathname to the DLL using the System.load(filename)
method instead.
Once load
or loadLibrary
succeeds, you need to make sure that the native function is named correctly. To aid in this, you can use javah
to generate a header file containing prototypes for all the native functions in a class.
More information about how to use JNI can be found in here and here.
EDIT: Also, the "Related" column to the right of this questions seems to contain several useful related question.
I try to create new project again.
So here is JNISample2.java file
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();
}
}
And here .h file that's generated by the javah -classpath . 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
Here is my .h file dll that I create VS2005 with MFC app.
// 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);
And here is my .cpp file
// 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);
}
After I use command prompt to run: java JNISample2, it display the string "from java Hello", but how come it does not display messagebox that I put inside the .cpp DLL file?
精彩评论