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

Delphi Discussion :

Utilisation de pByte


Sujet :

Delphi

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 11
    Par défaut Utilisation de pByte
    Bonjour voici mon probleme.

    J'utilise depuis mon appli DELPHI 7, les services d'une dll compilée en C++ Builder 5.0 (dont j'ai déclaré les prototypes via les mots clefs external, cdecl et Cie ...).



    L'appel d'un de ces services me pose problème :

    Prototype C :

    int _MaFonction (const unsigned char*, const unsigned char *, const long, unsigned char*, long, int* );


    La déclaration du prototype dans DELPHI :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    function _Mafonction( const  RF_CodeCmde : pByte;
                                  const  BufferIn : pByte;
                                  const  RF_TailleBufferIn : LongInt;
                                    RF_BufferOut : pByte;
                                    RF_TailleBufferOut : LongInt;
                                var RF_Status:integer):integer; cdecl; external 'MaDll.dll';

    Je peux bien appeler ce service mais le retour de la fontion est toujours négatif, comme s'il ne comprenait pas les valeurs passées. Voici un exemple :


    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
    var
      ret, status : integer;
      TailleQuestion, TailleReponse : LongInt;
     
      PReponse : ^Byte;
      pCodeService, pQuestion : ^Byte;
     
     
    begin
        TailleReponse := 3;
        GetMem (PReponse, TailleReponse*SizeOf(Byte));
     
        GetMem (pCodeService, 1);
        pCodeService^ := $01;
     
        TailleQuestion := 1;
        GetMem (pQuestion, TailleQuestion);
        pQuestion^ := $81;
     
        ret := _PerformCommand(pCodeService, pQuestion, TailleQuestion, pByte(PReponse), TailleReponse, status);
        // Cet appel renvoie toujours un statut KO, ret <>1 et status <0 signifiant 'paramètres invalides'
     
    end;


    J'ai tout inspecté au debuggeur sans rien remarquer de suspect. Je me pose donc 2 question :

    - Le choix d'un pByte pour décrire un unsigned char * est il judicieux ?
    - Faut il oui ou non garder le const devant les paramètres ?

    Merci de vos réponses ....


    Sebastien

  2. #2
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 089
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    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 : 14 089
    Par défaut
    prototype en C contient const, cela doit être comme dans Delphi à ceci près que const c'est un passage par pointeur, tu risque d'avoir ajouté un niveau d'indirection ... enlève ton const pour RF_CodeCmde, BufferIn et RF_TailleBufferIn

    en fait var et const c'est la même chose, c'est la même convention d'appel, c'est juste que dans l'IDE tu ne peux pas compiler une modification de la valeur (quoi qu'en ASM tu peux le faire paniquer à ce sujet)

    par exemple,
    oul'un et l'autre forme donnera en stdcall, la même chose ...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 11
    Par défaut
    Citation Envoyé par ShaiLeTroll
    l'un et l'autre forme donnera en stdcall, la même chose ...
    Je n'utilise pas stdcall mais cdecl.

    A ce propos, quelqu'un peut il m'expliquer la différence entre stdcall et cdecl (mes recherches sur Internet donnent sur ce sujet des explications plutot pas claires)

  4. #4
    Membre éclairé Avatar de Dirk-Pitt
    Inscrit en
    Juillet 2007
    Messages
    71
    Détails du profil
    Informations personnelles :
    Âge : 65

    Informations forums :
    Inscription : Juillet 2007
    Messages : 71
    Par défaut
    Extrait de l'aide de Delphi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Directive|Parameter order|Clean-up|Passes parameters in registers?
    register|Left-to-right|Routine|Yes
    pascal|Left-to-right|Routine|No
    cdecl|Right-to-left|Caller|No
    stdcall|Right-to-left|Routine|No
    safecall|Right-to-left|Routine|No
    La différence se situe au niveau du dépilement des paramètres.

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 11
    Par défaut
    Oups j'avais oublié de faire F1

  6. #6
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 089
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    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 : 14 089
    Par défaut
    Citation Envoyé par Cheb09
    Je n'utilise pas stdcall mais cdecl.
    Je sais mais ne connaissant pas cdecl, je ne me suis prononcé que sur ce que j'avais testé, d'ailleurs sans les const ... est-ce que cela donne un résultat, ou simplement laisser le const mais remplaer PByte par Byte ?
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  7. #7
    Membre émérite
    Avatar de CapJack
    Homme Profil pro
    Prof, développeur amateur vaguement éclairé...
    Inscrit en
    Mars 2004
    Messages
    624
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Prof, développeur amateur vaguement éclairé...
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2004
    Messages : 624
    Par défaut
    Citation Envoyé par ShaiLeTroll
    en fait var et const c'est la même chose, c'est la même convention d'appel, ...
    Je ne suis pas tout à fait d'accord avec toi.

    Pour un passage de paramètres register (par défaut), la convention var renverra toujours un pointeur sur la variable, car la variable doit être modifiée, il faut donc toujours accéder à son emplacement.

    Alors que si la directive const renvoie un pointeur sur la variable, c'est justement parce que la variable ne peut pas être modifiée, il n'y a donc pas besoin d'en faire une copie, on peut aller chercher les données là où elles sont.

    Mais ce n'est absolument pas obligé ! Le compilateur ne transmettra la valeur via l'adresse de la variable que s'il y calcule un intérêt en termes de temps d'exécution, c'est-à-dire si la taille de la variable excède le contenu d'un registre 32 bits (types record par exemple). Dans le cas de valeurs scalaires occupant moins de 4 octets, ou de pointeurs, c'est la valeur qui est directement manipulée parce qu'elle génèrera un code plus compact et plus rapide.

    Donc, ce n'est pas équivalent.

    Maintenant, dans le cas qui nous intéresse, d'une part je ne sais pas si ce que je viens d'écrire s'applique à la convention cdecl, et en outre il s'agit de pointeurs, donc en convention pascal ça ne changerait rien.

    Il faut essayer sans les directives const, et - sait-on jamais ? -, avec des directives var. Qui sait ? Si ça se trouve, BCB considère qu'un char* en const est un pointeur sur un pointeur... ?

    Remplacer PByte par Byte me paraît inapproprié, par contre moi je traduis toujours unsigned char * par PChar, mais c'est un choix.

    Edit : serais-je malade ? Je me suis trompé : ce n'est pas en convention pascal que le compilateur fait ce que je raconte plus haut, mais en convention par défaut, donc register. Corrigé.

Discussions similaires

  1. utiliser les tag [MFC] [Win32] [.NET] [C++/CLI]
    Par hiko-seijuro dans le forum Visual C++
    Réponses: 8
    Dernier message: 08/06/2005, 15h57
  2. Réponses: 4
    Dernier message: 05/06/2002, 14h35
  3. utilisation du meta type ANY
    Par Anonymous dans le forum CORBA
    Réponses: 1
    Dernier message: 15/04/2002, 12h36
  4. [BCB5] Utilisation des Ressources (.res)
    Par Vince78 dans le forum C++Builder
    Réponses: 2
    Dernier message: 04/04/2002, 16h01
  5. Réponses: 2
    Dernier message: 20/03/2002, 23h01

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