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

Langage Delphi Discussion :

PAnsiChar et DLL


Sujet :

Langage Delphi

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 152
    Points : 61
    Points
    61
    Par défaut PAnsiChar et DLL
    Bonjour,
    j'ai commencé à coder en delphi depuis une semaine et je me retrouve face à un petit probleme.
    Je souhaiterai traduire en delphi la fonction en C suivante :

    void PrintStat(NCTYPE_STATUS status, char *source)
    {
    char statusString[1024];

    if (status != 0)
    {
    ncStatusToString(status, sizeof(statusString), statusString);
    printf("\n%s\nSource = %s\n", statusString, source);
    }
    }
    voici ce que j'ai realisé :

    var
    StatusString : PAnsiChar;
    begin
    if statut <> 0 then
    begin
    ncStatustoString(statut, SizeOf(StatusString) ,StatusString);
    ShowMessage('Fonction : ' + source + ' Erreur : ' + StatusString);
    end;
    end;
    Le probleme est qu'a l'affichage, la valeur de StatusString n'est pas coherente. Meme si je marque StatusString^ dans le show message.

    Je ne sais pas si c'est un probleme lié à la DLL appellé par ncStatusToString, ou bien parceque StatusString n'est pas bien lu ou ecrite.


    Merci pour avoir lu ma question.
    Sapin

  2. #2
    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
    SizeOf = Taille de la variable, un PAnsiChar, c'est un pointeur, donc 4 octets ... c'est un premier problème

    Si tu fais du C, tu dois savoir qu'il faut allouer un pointeur, en Delphi, c'est pareil, GetMem\FreeMem au lieu de malloc\free, sinon, autant écrire le code via un tableau fixe, cela sera plus simple

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    var
      StatusString : array[0..1023] of Char;
    begin
      if statut <> 0 then
      begin
       ncStatustoString(statut, Length(StatusString), @StatusString);
       ShowMessage('Fonction : ' + source + ' Erreur : ' + StatusString);
      end;
    end;
    SizeOf devrait renvoyé bien 1024 car StatusString est une tableau fixe (un tableau dynamique étant un pointeur, cela n'aurait renvoyé que 4), mais on lui préférera Length qui fonctionne pour tous les cas, y compris pour les chaines ...

    Sinon, tu as Format qui peut jouer le rôle du PrintF ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ShowMessage(Format(#13'%s'#13'Source = %s'#13, [statusString, source]));

  3. #3
    Membre chevronné

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    1 519
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 519
    Points : 2 153
    Points
    2 153
    Billets dans le blog
    1
    Par défaut
    Bonjour et bienvenue sur Developpez.com.

    Mmmmh je ne sais pas ce que sais que ncStatusToString mais par contre la déclaration est différente entre le C et Delphi : en C tu déclare un tableau de 1024 caractères alors qu'en Delphi tu ne définis qu'un pointeur sur Char, il faut donc allouer la chaîne (de 1024 octets par exemple) avant en utilisant GetMem par 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
    var
     StatusString : PAnsiChar;
    begin
      if statut <> 0 then
      begin
        GetMem( StatusString, 1024 );
        try
          ncStatustoString(statut, SizeOf(StatusString) ,StatusString);
          ShowMessage('Fonction : ' + source + ' Erreur : ' + StatusString);
        finally
          FreeMem( StatusString );
        end;
      end;
    end;

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 152
    Points : 61
    Points
    61
    Par défaut
    Merci pour le conseil pour l'allocation, j'était passé à coté.
    Malheuresement ca ne résoud toujours pas mon probleme.

    J'ai remarqué quelque chose en debugant. Voici la "declaration" que j'ai faite de ncStatutToString :

    Function ncStatusToString( Status : NCTYPE_STATUS;
    SizeofString : NCTYPE_UINT32;
    MessageErreur :NCTYPE_STRING) : String; StdCall;
    lorsque je debug, je constate que la valeur de Status n'est pas egale a la valeur de statut de cet appel :
    ncStatustoString(statut, SizeOf(StatusString) ,StatusString);
    Edit : la fonction statustostring prend un entier comme parametre et retour le message d'erreur aproprié dans la chaine MessageErreur.

    Ca a peut etre un rapport ?

  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
    Juste, le type "string" n'est pas conseillé pour les DLL si tu n'utilise pas ShareMem ou FastShareMem ...

    en C
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      typedef char * NCTYPE_STRING;
    en Delphi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    type
      NCTYPE_STRING = PAnsiChar;
    essaye plutôt ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    procedure ncStatusToString(Status: NCTYPE_STATUS;
    SizeofString: NCTYPE_UINT32;
    MessageErreur: NCTYPE_STRING); StdCall;

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 152
    Points : 61
    Points
    61
    Par défaut
    J'utilise des fonction d'une DLL en fait, et ncStatusString fait partie de cette dll.
    Je ne peut donc pas modifié le type NCTYPE_STRING ni la declaration de ncStatueToString

    Ca m'étonne aussi que ca soit une fonction car le retour n'est pas explicité.
    Voici un bout de code suplementaire :

    Function ncStatusToString( Status : NCTYPE_STATUS;
    SizeofString : NCTYPE_UINT32;
    MessageErreur :NCTYPE_STRING) : String; External 'NICAN.DLL';
    Si j'ai bien compris, la chaine MessageErreur est modifié eb fonction du Status.

  7. #7
    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
    je n'ai pas dit de modifier la DLL, j'ai dit de changer ta déclaration du côté delphi et de vérifier tes types, avec cette DLL (National Instrument), n'as tu donc pas le fichier Header en C fourni ou une Doc ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    procedure ncStatusToString(Status: NCTYPE_STATUS;
    SizeofString: NCTYPE_UINT32;
    MessageErreur: NCTYPE_STRING); StdCall; External 'NICAN.DLL';
    procedure c'est "l'équivalent" du void du C ...

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 152
    Points : 61
    Points
    61
    Par défaut
    Ca fonctionne parfaitement maintenant.
    Je te remercie ShaiLeTroll

    Pourquoi est ce que le fait que ca soit declarré en function me faisait planter?
    Si jamais t'as une idée

  9. #9
    Membre chevronné

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    1 519
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 519
    Points : 2 153
    Points
    2 153
    Billets dans le blog
    1
    Par défaut
    Ben tu avais déclaré la méthode de ta DLL comme devant retourné un String (déjà c'est pas bon d'utiliser ce type pour les DLL) alors qu'elle ne retournait rien (void ou procédure comme le disais ShaiLeTroll) donc du coup ben vu que les signatures ne sont pas les mêmes...

  10. #10
    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
    En fait, le résultat, c'est une sorte de paramètre supplémentaire ... c'est un problème de pose des paramètres sur la pile ou l'utilisation des registres, ne connaissant que le cas d'une fonction avec type ordinal qui utilise AX, je ne peut pas plus expliquer que cela, mais un tuto sur le forum doit bien en parler ...

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 152
    Points : 61
    Points
    61
    Par défaut
    Oui, si je fait le parallele avec le c ou le c++ je comprend mieux le probleme.
    Ce qui m'as perdu c'est que je n'ai pas developpé cette fonction et je n'ai pas bien compris le parametre de sortie.
    Mea Culpa

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

Discussions similaires

  1. Pansichar - PwideChar et parametre de fonction DLL
    Par petitcoucou31 dans le forum Langage
    Réponses: 2
    Dernier message: 06/12/2014, 18h27
  2. Declarer une dll Delphi ?
    Par DelphiCool dans le forum C++Builder
    Réponses: 2
    Dernier message: 26/07/2002, 10h07
  3. Débug de DLL
    Par Bayard dans le forum C++Builder
    Réponses: 3
    Dernier message: 22/07/2002, 15h08
  4. Equivalent à ExeName pour une DLL
    Par Smortex dans le forum Langage
    Réponses: 7
    Dernier message: 16/07/2002, 21h07
  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