1. #1
    Membre habitué

    Inscrit en
    février 2007
    Messages
    211
    Détails du profil
    Informations personnelles :
    Âge : 46

    Informations forums :
    Inscription : février 2007
    Messages : 211
    Points : 157
    Points
    157

    Par défaut SWIG : Conversion int * (C++) vers int[] (java)

    Bonjour à tous.

    Dans le cadre d'un vaste projet, on utilise habituellement SWIG pour permettre de faire des bindings de librairies C++ vers Java et C#.
    La plupart du temps, ces binding, utilisant SWIG sont déjà fournis (GDal / LibTiff / LibGeotiff, etc).
    Pour une libairie Shapefil ce binding SWIG n'est pas fourni.
    Je cherche donc à savoir Comment accéder à un champ "int *" d'une structure C++ en le bindant vers int[] de java.
    La compilation (makefile.vc) ainsi les fichiers shapelib_swig.i sont déja fournis.
    Les précédents développeurs ne sont pas fait chier, ils ont directement modifiés le fichier original shapefil.h comme suit (je ne donne qu'une partie du fichier) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    /* -------------------------------------------------------------------- */
    /*      SHPObject - represents on shape (without attributes) read       */
    /*      from the .shp file.                                             */
    /* -------------------------------------------------------------------- */
    /* 
     * SWIG - TopoBase - pour traiter les tableaux padfX, padfY, padfZ et padfM ci-dessous, il faut donner une version modifiée du typemap
     * qui s'applique (on a sinon une erreur de compilation avec FillMeInAsSizeCannotBeDeterminedAutomatically car SWIG est incapable de calculer
     * la longueur du tableau
     * le typemap modifié utilise la longueur stockée dans nVertices
     */
    typedef struct
    {
        int		nSHPType;
     
        int		nShapeId; /* -1 is unknown/unassigned */
     
        int		nParts;
    	/* SWIG - TopoBase - panPartStart et panPartType doivent être déclarés comme des tableaux de taille nParts */
    #ifdef SWIG
    %typemap(out) int[] 
    %{$result = SWIG_JavaArrayOutInt(jenv, $1, (arg1)->nParts); %}
        int		panPartStart[];
        int		panPartType[];
    #else
        int		*panPartStart;
        int		*panPartType;
    #endif
     
        int		nVertices;
    	/* SWIG - TopoBase - padfX, padfY, padfZ et padfM doivent être déclarés comme des tableaux de taille nVertices */
    #ifdef SWIG
    %typemap(out) double[] 
    %{$result = SWIG_JavaArrayOutDouble(jenv, $1, (arg1)->nVertices); %}
        double	padfX[];
        double	padfY[];
        double	padfZ[];
        double	padfM[];
    #else
        double	*padfX;
        double	*padfY;
        double	*padfZ;
        double	*padfM;
    #endif
        double	dfXMin;
        double	dfYMin;
        double	dfZMin;
        double	dfMMin;
     
        double	dfXMax;
        double	dfYMax;
        double	dfZMax;
        double	dfMMax;
    } SHPObject;
    Mais ce n'est pas une bonne idée, car à chaque mise à jour il faut alors re-patcher le fichier original.
    J'ai donc supprimé tous les #ifdef SWIG pour retrouver le code original et essayé de donner à SWIG les indications afin de transformer les appels pour que côté Java on utilise des int[] alors que côté C++ on a des int *
    J'ai modifié le fichier shapelib_swig.h (compilé par makefile.vc)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    // Module s'appelle org.shapelib.swig.shapelib
    %module shapelib
     
    // various.i permet l'utilisation de : 
    //   "char * BYTE" pour traiter un char * comme un tableau de byte plutôt que comme une String (qui est "non mutable")
    //   typemaps.i permet l'utilisation de INPUT et OUTPUT 
     
    %include "arrays_java.i";
    %include "various.i";
    %include "typemaps.i";
     
    // Structure SHPObject => panPartStart et panPartType doivent être déclarés comme des tableaux de taille nParts
    %typemap(out) int * panPartStart %{ $result = SWIG_JavaArrayOutInt(jenv, $1, (arg1)->nParts); %}
    %typemap(out) int * panPartType  %{ $result = SWIG_JavaArrayOutInt(jenv, $1, (arg1)->nParts); %}
     
    // padfX, padfY, padfZ et padfM doivent être déclarés comme des tableaux de taille nVertices
    %typemap(out) double* padfX %{$result = SWIG_JavaArrayOutDouble(jenv, $1, (arg1)->nVertices); %}
    %typemap(out) double* padfY %{$result = SWIG_JavaArrayOutDouble(jenv, $1, (arg1)->nVertices); %}
    %typemap(out) double* padfZ %{$result = SWIG_JavaArrayOutDouble(jenv, $1, (arg1)->nVertices); %}
    %typemap(out) double* padfM %{$result = SWIG_JavaArrayOutDouble(jenv, $1, (arg1)->nVertices); %}
     
    // Include
    %{ #include "../../../shapefil.h" %}
     
    %include "../../shapefil.h"
    Mais ça ne semble pas suffisant, le code Java généré attend toujours des SWIG_type_p_int pour accéder aux variables panPartStart et panPartType, ce qui est impossible à créer côté jave (en plus if faudrait modifier TOUT le code déjà existant qui y accède via des int[]).
    Je lis la doc de SWIG qui est plus que fumeuse depuis 48h00 et je recherche sur internet ce genre de problème en java mais pour le moment je suis dans l'impasse.
    J'aimerais simplement transformer les appels int * vers du int[] et ça serait bon.
    Je ne sais pas comment faire, ni à quel moment les int * sont alloués / désalloués dans la structure (fuite mémoire)
    Comment les copier, etc.
    Je recherche des wiki simple sur le binding en java avec SWIG mais il y a peu de littérature et encore moins en Français (moins grave).
    Si certains sont experts en SWIG je veux bien un peu d'aide.
    Il y a aussi des fonctions avec des int * mais ça je les ai résolu avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    // on modifie 
    //  - 'char * pszFieldName' en 'char * BYTE' pour appliquer un typemap défini dans various.i
    //    qui va générer une interface java avec des tableaux de byte plutôt qu'un String 
    //    (qui est "non mutable" et qui ne peut donc pas récupérer une valeur)
    //  - 'int * pnWidth' et 'int * pnDecimals' en 'int * OUTPUT' pour appliquer un typemap défini dans typemaps.i
    //    qui va générer une interface java avec des tableaux de int
    %apply char *BYTE  { char * pszFieldName };
    %apply int *OUTPUT { int * pnWidth, int * pnDecimals };

  2. #2
    Membre habitué

    Inscrit en
    février 2007
    Messages
    211
    Détails du profil
    Informations personnelles :
    Âge : 46

    Informations forums :
    Inscription : février 2007
    Messages : 211
    Points : 157
    Points
    157

    Par défaut

    Le fichier retravaillé est disponible à cette adresse : SWIG utiliser un StringBuilder au lieu d'un String

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Conversion de String vers int
    Par CyberSlan dans le forum C++
    Réponses: 21
    Dernier message: 30/05/2008, 08h39
  2. [C#] Conversion implicite de type object vers int
    Par alexking2005 dans le forum C#
    Réponses: 5
    Dernier message: 02/01/2007, 10h02
  3. conversion string vers int
    Par mathher dans le forum C++
    Réponses: 4
    Dernier message: 14/04/2006, 17h52
  4. Conversion float vers int
    Par vargasvan dans le forum C
    Réponses: 2
    Dernier message: 05/10/2005, 17h29
  5. Conversion VARCHAR vers INT
    Par Slash dans le forum MS SQL-Server
    Réponses: 3
    Dernier message: 17/05/2005, 10h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo