IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

API, COM et SDKs Delphi Discussion :

Programme C vers Delphi, pointeur et Access Violation


Sujet :

API, COM et SDKs Delphi

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    147
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Mars 2006
    Messages : 147
    Points : 84
    Points
    84
    Par défaut Programme C vers Delphi, pointeur et Access Violation
    Bonjour,

    J'ai ce code en C. Il s'agit d'un exemple en C fourni par un éditeur pour utiliser sa DLL:

    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
     
    typedef struct
    {
        //@{
        double latitude;
        double longitude;
        //@}
        double hpe;
        unsigned short nap;
        double speed;
        double bearing;
        WPS_StreetAddress* street_address;
        unsigned short ncell;
        unsigned short nsat;
        double altitude;
        WPS_LocationType type;
        unsigned long age;
    } WPS_Location;
     
    WPSAPI_EXPORT WPS_ReturnCode WPSAPI_CALL
    WPS_location(const WPS_SimpleAuthentication* authentication,
                 WPS_StreetAddressLookup street_address_lookup,
                 WPS_Location** location);
     
    WPSAPI_EXPORT void WPSAPI_CALL
    WPS_free_location(WPS_Location*);
     
     
    WPS_Location* location;
    rc = WPS_location(&authentication, WPS_NO_STREET_ADDRESS_LOOKUP,
                                  &location);
    if (rc != WPS_OK){
        // traitement de l'échec....
    }
    else
    {
        // Traitement du succès ....
     
        // Puis libération ressource
        WPS_free_location(location);
    }
    (A ce sujet, les //@{ //@} en début de structure ont-ils une signification ???)

    Dans ce code, je ne vois aucune allocation de mémoire pour "location", qui n'est pourtant, sauf erreur, qu'un pointeur. J'en déduis que cette allocation est faite par l'appel de la fonction WPS_location(). Ensuite, WPS_free_location libère la mémoire allouée précédemment. Me trompe-je ?


    Pourtant, si je traduis la chose sous delphi, j'ai un access violation si je ne fais pas un GetMemory sur le même pointeur (PLocation ici) avant d'appeler la même fonction :

    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
    54
    55
    56
    57
     
    type
    TWPS_Location = record
      latitude : double;
      longitude : double;
      hpe : double;     
      nap: word;        
      speed: double;   
      bearing: double; 
      street_addresse: PWPS_StreetAddress;
      ncell: Word;     
      nsat: Word;     
      altitude: double;
      loctype : WPS_LocationType;
      age: LongInt;
    end;
    PTWPS_Location = ^TWPS_Location;
     
    FWPS_location = function (
      Pauthentication : PWPS_SimpleAuthentication;
      street_address_lookup: WPS_StreetAddressLookup;
      location: PPTWPS_Location):WPS_ReturnCode; cdecl;
     
    FWPS_free_location = procedure (
      location: PTWPS_Location) cdecl;
     
    var
      Plocation: PTWPS_location;
      retour : WPS_ReturnCode;
     
      WPS_location : FWPS_location;
      WPS_free_location : FWPS_free_location;
     
     
    Begin
     
      DLLHandle := LoadLibrary(WpsDll);
      @WPS_location := GetProcAddress(DLLHandle, 'WPS_location') ;
     
      // Si je ne fais pas ça, ACCESS VIOLATION lors de l'appel à WPS_location() à la ligne suivante
      Plocation := GetMemory(SizeOf(TWPS_location));
      retour := WPS_location(@authentication, WPS_NO_STREET_ADDRESS_LOOKUP,@Plocation);
      if retour <> WPS_OK then begin
        // Traitement de l'échec
     
      end
      else begin
        // Traitement du retour....
     
       // Libération ressource  
       WPS_free_location(Plocation);
      end;
     
      // MAIS SI JE FAIS CA AUSSI : ACCESS VIOLATION dans le cas où WPS_free_location(Plocation); a déjà été appelée...
      freememory(PLocation);
     
      FreeLibrary(DLLHandle);
    Ne connaissant pas C, je pense que quelque chose m'échappe. Merci d'avance pour vos lumières.

    André.

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    147
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Mars 2006
    Messages : 147
    Points : 84
    Points
    84
    Par défaut
    Peut-être une idée :

    Il semblerait que de déclarer la fonction de cette façon:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    FWPS_location = function (
      Pauthentication : PWPS_SimpleAuthentication;
      street_address_lookup: WPS_StreetAddressLookup;
      var location: PTWPS_Location):WPS_ReturnCode; cdecl;
    au lieu de

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    FWPS_location = function (
      Pauthentication : PWPS_SimpleAuthentication;
      street_address_lookup: WPS_StreetAddressLookup;
      location: PPTWPS_Location):WPS_ReturnCode; cdecl;
    résolve le problème : Plus besoin de GetMemory, et plus d'access violation.

    Si un fin connaisseur C pouvait me confirmer la chose

  3. #3
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 586
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 586
    Points : 25 262
    Points
    25 262
    Par défaut
    Ben n'était-ce pas la proposition de Paul TOTH

    Sinon un fin connaisseur du C, ne pourrait pas répondre à ta question !
    Il faut un connaisseur du C et de Delphi !
    Et je te confirme var va utiliser un pointeur et cela simplifie la syntaxe !

    Sinon à la place de GetMemory, tu pouvais faire new(Plocation);A place de FreeMemory un Dispose

    Par contre, c'est vrai que le code C ne semble pas allouer la mémoire, ce qui me semble logique puisque le WPS_free_location me fait penser que la mémoire est alloué côté DLL

    Essaye avec PPTWPS_Location et ce code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
      Plocation := nil;
      retour := WPS_location(@authentication, WPS_NO_STREET_ADDRESS_LOOKUP,@Plocation);
    Peut-être que WPS_location est prévu pour plusieurs appels sucessifs, si on lui passe un paramètre non null, il va le libérer
    En Delphi, les variables locales prennent une valeur aléatoire !
    En C, j'aurais dit pareil, sous C++Builder, un pointeur local prend une valeur aléatoire

    pas de new, comme * pas d'appel au "constructeur" de struct

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    147
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Mars 2006
    Messages : 147
    Points : 84
    Points
    84
    Par défaut
    Bon je viens de faire des tests "intensifs" sur Windows 7 (Delphi) et sur Mac OS 10.6 (compilation sous Lazarus).

    Dans les deux cas, plus aucun access violation avec la syntaxe effectivement plus élégante "var location: PTWPS_Location"...

    Je laisse tourner les pogrammes quelques jours pour vérifier la stabilité mais je pense que c'est bien ça : La DLL alloue et libère elle-même la mémoire.

    Et si un connaisseur C peut malgré tout m'expliquer cette étrange 'écriture:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    ...
    //@{
        double latitude;
        double longitude;
        //@}
    ...
    Ps : et oui c'etait bien la proposition de Toth

    Merci !
    André.

  5. #5
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 586
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 586
    Points : 25 262
    Points
    25 262
    Par défaut
    Rien !

    Code Original de cette lib :

    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
     
        //@{
        /**
         * the calculated physical geographic location
         */
        double latitude;
        double longitude;
        //@}
     
        /**
         * <em>horizontal positioning error</em> --
         * A calculated error estimate of the location result in meters
         */
        double hpe;
    ...
    C'est pour indiquer au générateur de documentation de mettre les deux variables ensemble

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    147
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Mars 2006
    Messages : 147
    Points : 84
    Points
    84
    Par défaut
    Merci pour l'info

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

Discussions similaires

  1. Migration Delphi-Access vers Delphi-SQL Server
    Par burkan dans le forum Bases de données
    Réponses: 5
    Dernier message: 05/05/2008, 03h31
  2. Delphi 7, Indy 10, IdFTP.pas et Access violation
    Par kernigansnotdead dans le forum Composants VCL
    Réponses: 4
    Dernier message: 04/02/2008, 09h10
  3. Conversion d'un programme en C vers Delphi.
    Par jbrg dans le forum Delphi
    Réponses: 1
    Dernier message: 21/03/2007, 12h51
  4. Depuis EDI DELPHI : Access Violation
    Par powerlog dans le forum EDI
    Réponses: 1
    Dernier message: 03/08/2005, 16h59
  5. [DELPHI][PROECEDURES STOCKES] Access violation
    Par All Jinx dans le forum Bases de données
    Réponses: 6
    Dernier message: 14/05/2004, 15h57

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