Java symbol lookup error

Fermé
Fellowes21 Messages postés 1 Date d'inscription mardi 16 mai 2017 Statut Membre Dernière intervention 16 mai 2017 - Modifié le 16 mai 2017 à 10:05
Bonjour,



Bonjour à tous.

En voulant appeler des fonctions C en java, cela me génère une erreur que je n'arrive pas à résoudre malgré mes recherches.
Voila le code:


public class InterfaceAvecC {
 
 static{
   System.load("/home/fuzier/Documents/hex2/src/libInterfaceAvecC.so");
 }
 
 public static native String creerGraphe(int n);

 
 
}



La fonction de test:


public class Test {

 
 private static void afficher(String s,int taille){
  int h=0;
  for(int j=0;j<=taille+1;j++){ /* boucle correspondant au nombre de ligne à afficher*/
   
   for(int a=0;a<j+1;a++)
    System.out.print(" ");
   
   if(j==0){
    /*  affichage de la première ligne  */
    for(int i=0;i<=taille;i++)
      System.out.print("W ");
   
    System.out.println("B");
   }
   
   
   /* affichage du centre */
   else if(j>0 && j<=taille){
    
    for(int x=0;x<=taille+1;x++){
     if(x==0 || x==taille+1)
      System.out.print("B ");
     else if(x>0 && x<taille+1){
      System.out.print(s.charAt(h) + " ");
      h++;
     }
      
    }
    System.out.println("");
   }
   else{ /* affichage dernière ligne */
    
    System.out.print("B ");
    for(int i=0;i<=taille;i++)
     System.out.print("W ");
  
   
    
   }
   
   
   
  }
  
 }
 

 
 public static void main(String[] args){       
    
  String s=InterfaceAvecC.creerGraphe(9);
  afficher(s,9);
 
 }
 
}

]

Et voici l'erreur:

/usr/lib/jvm/java-8-openjdk-amd64/bin/java: symbol lookup error: /home/fuzier/Documents/hex2/src/libInterfaceAvecC.so: undefined symbol: graphe_create



Voici aussi les fichiers .c et .h que j'utilise:


#include <stdlib.h>
#include <string.h>
#include "InterfaceAvecC.h"
#include "graphe.h"



JNIEXPORT jstring JNICALL
Java_InterfaceAvecC_creerGraphe (JNIEnv *env, jclass cl, jint ji) {


/* traitement en C */
Graphe g= graphe_create(ji);
char* res=graphe_toString(g);

/* conversion du résultat en chaîne Java */
jstring jres = (*env)->NewStringUTF(env, res);
/* libération mémoire */

return jres;

}



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

#ifndef _Included_InterfaceAvecC
#define _Included_InterfaceAvecC
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     InterfaceAvecC
 * Method:    creerGraphe
 * Signature: (I)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_InterfaceAvecC_creerGraphe
  (JNIEnv *, jclass, jint);

#ifdef __cplusplus
}
#endif
#endif





ça fait un long moment que je cherche mais je ne suis pas un expert malheureusement.

J'ai fait quelques test et je pense que cela peut aussi venir des fonctions appelé dans le code c alors je vous les donnes aussi:

Voila le .c

#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "graphe.h"
 
 
struct _cell{
    char key;
    Cell* cells;
};
struct _graphe{
    Cell head;
    Cell** groupsW; // memorise les groupes de cellules blanches
    size_t size_groupsW;
    Cell** groupsB; // memorise les groupes de cellules noires
    size_t size_groupsB;
    int size;
};
 
/**
 * Description: retourne une cellule avec le caractère key et les pointeurs de la cellule à NULL
 *
 * Numérotation des pointeurs:
 *
 *                0/\1
 *               5|  |2
 *                4\/3
 */
 
static Cell _createCell(char key){
    Cell c=malloc(sizeof(struct _cell));
    if(c==NULL){
        fprintf(stderr, "Allocation mémoire impossible.\n");
        return NULL;
    }
    c->cells=malloc(6*sizeof(Cell));
    if(c->cells==NULL){
        fprintf(stderr, "Allocation mémoire impossible.\n");
        return NULL;
    }
    c->key=key;
    for(int i=0; i<6; i++)
        c->cells[i]=NULL;
    return c;
}
 
 
Graphe graphe_create(int n){
    assert(n>1);
    Graphe g;
    Cell w,b; // les cotés
    Cell* temp;
    int x,y; // cordonnées d'une case
    int n_carre=n*n;
 
    w=_createCell('W');
    b=_createCell('B');
 
    g=malloc(sizeof(struct _graphe));
 
    if(g==NULL){
        fprintf(stderr,"Allocation mémoire impossible.\n");
        return NULL;
    }
 
    temp=malloc(n_carre*sizeof(Cell));
 
    if(temp==NULL){
        fprintf(stderr,"Allocation mémoire impossible.\n");
        return NULL;
    }
 
    for(int i=0; i<n_carre;i++)
        temp[i]=_createCell(VIDE);
 
 
    for(int i=0; i<n_carre;i++){
        x=i/n;
        y=i%n;
 
        if(y==0){
            temp[i]->cells[4]=b;
            temp[i]->cells[5]=b;
        }else{
            temp[i]->cells[5]=temp[i-1];
            if(x!=n-1)
                temp[i]->cells[4]=temp[i+n-1];
        }
 
        if(y==n-1){
            temp[i]->cells[1]=b;
            temp[i]->cells[2]=b;
        }else{
            temp[i]->cells[2]=temp[i+1];
        }
 
        if(x==0){
            temp[i]->cells[0]=w;
            temp[i]->cells[1]=w;
        }else{
            temp[i]->cells[0]=temp[i-n];
            if(y!=n-1)
                temp[i]->cells[1]=temp[i-n+1];
        }
 
        if(x==n-1){
            temp[i]->cells[3]=w;
            temp[i]->cells[4]=w;
        }else{
            temp[i]->cells[3]=temp[i+n];
        }
    }
 
 
    g->head=temp[0];
    g->size=n;
    g->groupsB=NULL;
    g->groupsW=NULL;
    g->size_groupsW=0;
    g->size_groupsB=0;
    free(temp);
    return g;
}
 
char* graphe_toString(Graphe g){
    Cell itr,mem;
    int n=g->size;
    int j=1;
    int i=0;
    char* c=malloc(2*(n*n)+1);
 
    itr=g->head;
    mem=itr;
    for(;itr->key!='W';){
 
        if(itr->key==VIDE)
            c[i]=itr->key;
        else
            c[i]=itr->key==BLANC?'o':'*';
 
        if(itr->cells[2]->key=='B'){
            c[i+1]='\n';
            j++;
            itr=mem->cells[3];
            mem=itr;
        }else{
            c[i+1]=' ';
            itr=itr->cells[2];
        }
        i=i+2;
    }
    c[i]='\0';
    return c;
}
 
void graphe_print(Graphe g){
    Cell itr,mem;
    int n=g->size;
    int j=1;
    for(int i=0;i<n;i++)
        printf("W ");
    printf("W/B\n");
 
    itr=g->head;
    mem=itr;
    for(;itr->key!='W';){
        if(itr->cells[5]->key=='B'){
            printf("%*s", j, "");
            printf("B ");
        }
        if(itr->key==VIDE)
            printf("%c ",itr->key);
        else
            printf("%s ",itr->key==BLANC?"o":"*");
 
        if(itr->cells[2]->key=='B'){
            printf("B\n");
            j++;
            itr=mem->cells[3];
            mem=itr;
        }else{
            itr=itr->cells[2];
        }
    }
 
    printf("%*s", n+1, "");
    printf("B/W ");
    for(int i=0;i<n;i++)
        printf("W ");
    printf("\n");
}
 
Graphe graphe_toGraphe(char* c){
    Graphe g;
    size_t c_len;
    int n=(int)sqrt((double)(c_len=strlen(c))/2);
    int temp;
    char car;
    Pion p;
    g=graphe_create(n);
    for(size_t i=0;i<c_len;i=i+2){
        temp=i/2;
        car=c[i];
        if(car=='o'||car=='*'){
            p=car=='o'?BLANC:NOIR;
            graphe_insert(&g,p,temp/n,temp%n);
        }
    }
    return g;
}
 
/**
 * Description: libère la mémoire d'une cellule c
 *
 * Précondition: c ≠ NULL ⋀ *c ≠ NULL
 */
 
static void _freeCell(Cell* c){
    assert(c!=NULL && *c!=NULL);
    free((*c)->cells);
    free(*c);
}
 
void graphe_destroy(Graphe* g){
    Cell itr,mem1,mem2;
    Cell** groupsW=(*g)->groupsW;
    Cell** groupsB=(*g)->groupsB;
    size_t i;
 
    for(i=0;i<(*g)->size_groupsB;i++)
        free(groupsB[i]);
    free(groupsB);
 
    for(i=0;i<(*g)->size_groupsW;i++)
        free(groupsW[i]);
    free(groupsW);
 
 
    itr=(*g)->head;
    mem1=itr->cells[3];
     
    for(;itr->cells[2]->key!='B'||itr->cells[3]->key!='W';){
        if(itr->cells[2]->key=='B'){
            _freeCell(&itr);
            itr=mem1;
            mem1=itr->cells[3];
        }else{
            mem2=itr->cells[2];
            _freeCell(&itr);
            itr=mem2;
        }
    }
    _freeCell(&itr->cells[2]);
    _freeCell(&itr->cells[3]);
    _freeCell(&itr);
    free(*g);
 
}
 
/**
 * Description: retourne la cellule de cordonnées (x,y) du graphe g
 *
 * Précondition:
 * Soit n, la taille de la grille g, on a:
 * g ≠ NULL ⋀ *g ≠ NULL ⋀ x∈[0,n[ ⋀ y∈[0,n[
 */
 
static Cell _getCell(Graphe g, int x, int y){
    assert(g!=NULL && x>=0 && x<g->size && y>=0 && y<g->size);
    Cell c=g->head;
    int i;
    for(i=0;i<x;i++)
        c=c->cells[3];
    for(i=0;i<y;i++)
        c=c->cells[2];
    return c;
}
 
bool graphe_isEmptyCell(Graphe g, int x, int y){
    assert(g!=NULL && x>=0 && x<g->size && y>=0 && y<g->size);
    return graphe_getCellContent(g,x,y)==VIDE;
}
 
/**
 * Description: permet de déterminer si les au moins une des arrêtes d'une cellule c pointe vers une cellule
 * d'un groupe de cellule
 *
 * Précondition: c!=NULL ⋀ group!=NULL
 */
 
static bool _asCellInCommon(Cell* group, Cell c){
    assert(c!=NULL && group!=NULL && *group!=NULL);
 
    for(int i=0;group[i]!=NULL;++i)
        for(int j=0;j<6;j++)
            if(c->cells[j]==group[i])
                return true;
    return false;
}
 
/*
 * Description: permet de placer une cellule c dans le bon groupe de cellules du graphe
 * et permet de fusionner des groupes de cellules si c possède des arrêtes communes entre des cellules
 * de ces deux groupes.
 *
 * Précondition: g!=NULL ⋀ c!=NULL ⋀ (c->key==NOIR ⋁ c->key==BLANC)
 */
 
static void _insertIntoGroups(Graphe g, Cell c){
    assert(g!=NULL && c!=NULL && (c->key==BLANC||c->key==NOIR));
    Cell*** groups;
    Cell* temp;
    size_t size_temp=1;
    size_t* size_groups;
    size_t j;
    if(c->key==NOIR){
        groups=&g->groupsB;
        size_groups=&g->size_groupsB;
    }else{
        groups=&g->groupsW;
        size_groups=&g->size_groupsW;
    }
 
    temp=malloc(2*sizeof(Cell));
    if(temp==NULL){
        fprintf(stderr, "Allocation mémoire impossible\n");
        return;
    }
    temp[0]=c;
    temp[1]=NULL;
 
    for(size_t i=0;i<(*size_groups);){
        if(_asCellInCommon((*groups)[i],c)){
            // on recopie les cellules de *groups[i] dans temp
            for(j=0;(*groups)[i][j]!=NULL;j++){
                temp=(Cell*)realloc(temp,(++size_temp+1)*sizeof(Cell));
                if(temp==NULL){
                    fprintf(stderr, "Allocation mémoire impossible\n");
                    return;
                }
                temp[size_temp-1]=(*groups)[i][j];
                temp[size_temp]=NULL;
            }
            free((*groups)[i]);
            for(j=i;j<(*size_groups)-1;j++)
                (*groups)[j]=(*groups)[j+1];
            *groups=(Cell**)realloc(*groups,--(*size_groups)*sizeof(Cell*));
        }else{
            i++;
        }
    }
    *groups=(Cell**)realloc(*groups,(++(*size_groups)+1)*sizeof(Cell*));
    if(*groups==NULL){
        fprintf(stderr, "Allocation mémoire impossible\n");
        return;
    }
    (*groups)[(*size_groups)-1]=temp;
    (*groups)[(*size_groups)]=NULL;
}
 
Graphe graphe_insert(Graphe* g, Pion p, int x, int y){
    assert(g!=NULL && *g!=NULL && x>=0 && x<(*g)->size && y>=0 && y<(*g)->size
            &&(p==BLANC||p==NOIR) && graphe_getCellContent(*g,x,y)==VIDE);
    Cell c=_getCell(*g,x,y);
    c->key=p;
 
    _insertIntoGroups(*g,c);
 
    return (*g);
}
 
/*
 * Description: renvoie vrai si c appartient à group, faux sinon
 *
 * Précondition: group!=NULL ⋀ *group!=NULL ⋀ c!=NULL
 */
 
static bool _cellInGroup(Cell* group, Cell c){
    assert(group!=NULL && *group!=NULL && c!=NULL);
    for(size_t i=0;group[i]!=NULL;i++)
        if(group[i]==c)
            return true;
    return false;
}
 
/*
 * Description: permet de retirer une cellule c du bon groupe de cellules du graphe auquel elle appartenait
 * et permet de séparer des groupes de cellules si c possèdait des arrêtes communes entre des cellules
 * de ce groupe.
 *
 * Précondition: g!=NULL ⋀ c!=NULL ⋀ (c->key==BLANC||c->key==NOIR)
 */
 
static void _removeFromGroups(Graphe g, Cell c){
    assert(g!=NULL && c!=NULL && (c->key==BLANC||c->key==NOIR));
     
    Cell*** groups;
    Cell* temp=NULL;
    size_t size_temp=0;
    size_t* size_groups;
    size_t i,j;
 
    if(c->key==NOIR){
        groups=&g->groupsB;
        size_groups=&g->size_groupsB;
    }else{
        groups=&g->groupsW;
        size_groups=&g->size_groupsW;
    }
 
    for(i=0;i<(*size_groups)&&!_cellInGroup((*groups)[i],c);i++);
    for(j=0;(*groups)[i][j]!=NULL;j++){
        if((*groups)[i][j]!=c){
            temp=realloc(temp,(++size_temp)*sizeof(Cell));
            temp[size_temp-1]=(*groups)[i][j];
        }
    }
    free((*groups)[i]);
    for(j=i;j<(*size_groups)-1;j++)
        (*groups)[j]=(*groups)[j+1];
    *groups=realloc(*groups,(--(*size_groups))*sizeof(Cell*));
 
    for(j=0;j<size_temp;j++)
        _insertIntoGroups(g,temp[j]);
    free(temp);
 
}
 
Graphe graphe_remove(Graphe* g, int x, int y){
    assert(g!=NULL && *g!=NULL && x>=0 && x<(*g)->size && y>=0 && y<(*g)->size
            && (graphe_getCellContent(*g,x,y)==NOIR||graphe_getCellContent(*g,x,y)==BLANC));
    Cell c=_getCell(*g,x,y);
    _removeFromGroups(*g,c);
    c->key=VIDE;
    return (*g);
}
 
char graphe_getCellContent(Graphe g, int x, int y){
    assert(g!=NULL && x>=0 && x<g->size && y>=0 && y<g->size);
    return _getCell(g,x,y)->key;
}
 
 
Cell** graphe_getGroups(Graphe g, Pion p){
    assert(g!=NULL && (p==BLANC||p==NOIR));
    return p==NOIR?g->groupsB:g->groupsW;
}
 
size_t graphe_countGroups(Graphe g, Pion p){
    assert(g!=NULL && (p==BLANC||p==NOIR));
    return p==NOIR?g->size_groupsB:g->size_groupsW;
}
 
/*
 * Description: renvoie vrai si le pion passé en paramètre est la couleur gagnante.
 *
 * Précondition: g ≠ NULL ⋀ (p=NOIR ⋁ p=BLANC)
 */
 
static bool _detectWinner(Graphe g, Pion p){
    assert(g!=NULL && (p==NOIR || p==BLANC));
 
    Cell** groups=graphe_getGroups(g,p);
    bool w1,w2,b1,b2; // permettent de savoir si les arrêtes d'une cellule sont en contact avec un bord du plateau
    w1=false;
    w2=false;
    b1=false;
    b2=false;
 
    if(groups==NULL)
        return false;
 
    for(size_t i=0;groups[i]!=NULL&&(!w1||!w2)&&(!b1||!b2);i++){
        w1=false;
        w2=false;
        b1=false;
        b2=false;
        for(size_t j=0;groups[i][j]!=NULL&&(!w1||!w2)&&(!b1||!b2);j++){
            if(p==BLANC){
                if(groups[i][j]->cells[0]->key=='W')
                    w1=true;
                else if(groups[i][j]->cells[3]->key=='W')
                    w2=true;
            }else{
                if(groups[i][j]->cells[2]->key=='B')
                    b1=true;
                else if(groups[i][j]->cells[4]->key=='B')
                    b2=true;
            }
        }
    }
    return (w1&&w2)||(b1&&b2);
 
}
 
char graphe_detectWinner(Graphe g){
    assert(g!=NULL);
    if(_detectWinner(g,NOIR))
        return NOIR;
    else if(_detectWinner(g,BLANC))
        return BLANC;
    return VIDE;
}
 
int graphe_getSize(Graphe g){
    return g->size;
}


le .h


 
#ifndef GRAPHE_H_
#define GRAPHE_H_
 
#include <stdbool.h>
 
#define BLANC 'b'
#define NOIR  'n'
#define VIDE '.'
 
typedef char Pion;
typedef struct _cell * Cell;
typedef struct _graphe * Graphe;
 
/* Constructeurs */
 
/**
 * Description: crée un graphe de à partir d'une taille n
 * et retourne le graphe initialisé avec des cases vides.
 * Précondition: n>1
 */
Graphe graphe_create(int n);
 
/**
 * Description: Insère un pion p dans un graphe g aux cordonnées (x,y)
 * et retourne le nouveau graphe.
 *
 * Précondition:
 * Soit n, la taille de la grille g, on a:
 *   g ≠ NULL ⋀ *g ≠ NULL ⋀ (p=NOIR ⋁ p=BLANC) ⋀ x∈[0,n[ ⋀ y∈[0,n[ ⋀ graphe_isEmptyHex(*g,x,y)
 * ⋀ graphe_getCellContent(*g,x,y)=VIDE
 */
Graphe graphe_insert(Graphe* g, Pion p, int x, int y);
 
/**
 * Descrition: Supprime le pion dans le graphe g placé aux cordonnées (x,y)
 * et retourne le nouveau graphe.
 * 
 * Précondition:
 * Soit n, la taille de la grille g, on a:
 *   g ≠ NULL ⋀ *g ≠ NULL ⋀ x∈[0,n[ ⋀ y∈[0,n[
 * ⋀ (graphe_getCellContent(*g,x,y)=NOIR ⋁ graphe_getCellContent(*g,x,y)=BLANC)
 *
 */
Graphe graphe_remove(Graphe* g, int x, int y);
 
 
/* Projecteurs */
 
/**
 * Description: retourne vrai si la cellule du graphe g de cordonnées (x,y)
 * est vide,
 * renvoie faux sinon.
 *
 * Précondition:
 * Soit n, la taille de la grille g, on a:
 * g ≠ NULL ⋀ x∈[0,n[ ⋀ y∈[0,n[
 */
bool graphe_isEmptyCell(Graphe g, int x, int y);
 
/**
 * Description:
 * La fonction retourne BLANC si le joueur blanc a gagné.
 * La fonction retourne NOIR si le joueur noir a gagné.
 * La fonction retourne VIDE sinon
 *
 * Précondition: g ≠ NULL
 */
char graphe_detectWinner(Graphe g);
 
/**
 * Description: retourne le contenu d'une cellule de cordonnées (x,y)
 * dans un graphe g
 *
 * Précondition: g ≠ NULL ⋀ x∈[0,n[ ⋀ y∈[0,n[
 */
char graphe_getCellContent(Graphe g, int x, int y);
 
/**
 * Description: retourne les groupes de cellules dont le contenu est p
 *
 * Précondition: g ≠ NULL ⋀ (p=NOIR ⋁ p=BLANC)
 */
 
Cell** graphe_getGroups(Graphe g, Pion p);
 
/**
 * Description: retourne le nombre des groupes de cellules dont le contenu est p
 *
 * Précondition: g ≠ NULL ⋀ (p=NOIR ⋁ p=BLANC)
 */
 
size_t graphe_countGroups(Graphe g, Pion p);
 
/*
 * Description: retourne la taille d'un graphe passé en paramètre
 *
 * Précondition: g ≠ NULL
 */
int graphe_getSize(Graphe g);
 
 
/**
 * Description: imprime le graphe sur la sortie standard au format ascii
 *
 * Précondition: g ≠ NULL
 */
void graphe_print(Graphe g);
 
/**
 * Description: retourne une chaine de caractères representant le graphe au format ascii
 *
 * Précondition: g ≠ NULL
 */
char* graphe_toString(Graphe g);
 
/**
 * Description: transforme une chaine de caractères representant le graphe au format ascii en type Graphe
 *
 * Précondition: c ≠ NULL ⋀ *c ≠ NULL
 */
Graphe graphe_toGraphe(char* c);
 
/* Destructeurs */
 
/**
 * Description: détruit un graphe g passé en paramètre
 *
 * Précondition: g ≠ NULL ⋀ *g ≠ NULL
 */
void graphe_destroy(Graphe* g);
 
 
#endif



Merci infiniment pour votre aide!
A voir également: