2010-01-26 7 views
0

Ceci est mon deuxième codage Java et ne référence jamais aucune bibliothèque externe avant. Je suis les exemples JNI en ligne et je reçois UnsatisfiedLinkError en essayant de charger la DLL. Je pensais que je devais créer une DLL avant d'essayer de charger, mais tous les exemples que j'ai regardés ne mentionnent pas la création de DLL. La plupart d'entre eux déclarant que je devrais d'abord créer du code Java puis du code natif.Eclipse Java JNI, erreur de liaison 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"); 
} 

} 

Comment puis-je éviter l'erreur?

Répondre

1

L'exemple de code que vous fournissez suppose qu'il existe une DLL dans le chemin de recherche appelé MyLittleJNI.dll, contenant une méthode displayHelloWorld. Le nom de la fonction C dans la DLL est décoré en utilisant une syntaxe bien définie.

Si vous obtenez un UnsatisfiedLinkError dans loadLibrary(), c'est parce que la JVM ne trouve pas la DLL. Vous pouvez éviter le problème temporairement en spécifiant le chemin d'accès complet à la DLL à l'aide de la méthode System.load(filename) à la place.

Une fois que load ou loadLibrary a réussi, vous devez vous assurer que la fonction native est nommée correctement. Pour faciliter cela, vous pouvez utiliser javah pour générer un fichier d'en-tête contenant des prototypes pour toutes les fonctions natives d'une classe.

Vous trouverez plus d'informations sur l'utilisation de JNI dans here et here.

EDIT: Aussi, la colonne "Related" à la droite de cette question semble contenir plusieurs questions connexes utiles.

+0

merci pour vos réponses. J'ai finalement eu le lien, mais la fonction dans ma DLL ne s'affiche pas. Peut-être que j'ai eu la signature de la fonction erronée. – phillip

+0

Si la signature de votre fonction est incorrecte, l'appel de la fonction depuis Java doit déclencher une exception. Si aucune exception n'est levée mais que votre sortie n'apparaît toujours pas, alors quelque chose d'autre est faux. – JesperE

0

Je réessaie de créer un nouveau projet.

Voici donc JNISample2.java fichier

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

} 

Et ici .h qui est généré par le -classpath javah. 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 

Voici ma DLL de fichier .h que je crée VS2005 avec l'application 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); 

Et voici mon fichier .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); 
} 

Après j'utiliser l'invite de commande pour exécuter: java JNISample2, il affiche la chaîne « de java Bonjour », mais comment se fait-il ne montre pas messagebox que j'ai mis dans le fichier DLL .cpp?

+0

Ne posez pas de nouvelles questions dans une réponse. Modifiez votre question ou posez une nouvelle question. – JesperE

+0

Votre point d'entrée JNI doit être compilé avec C-linkage, donc vous devez mettre 'extern 'C" {...} 'autour du prototype de la fonction. – JesperE

+0

merci de souligner les règles et règlements. Yeahh je devrais poser une nouvelle question .. – phillip