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

WinDev Discussion :

Problème paramètres fonction API


Sujet :

WinDev

  1. #1
    Membre actif Avatar de peijnoob
    Profil pro
    Développeur informatique
    Inscrit en
    Août 2006
    Messages
    279
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 279
    Points : 294
    Points
    294
    Par défaut Problème paramètres fonction API
    Bonjour à tous,

    Je dois communiquer avec une dll afin de récupérer des informations.

    Dans cette dll, il y a une fonction ReceiveMsg, avec tout plein de paramètres de types différents (pas mal de pointeurs) et je n'arrive pas à l'appeler correctement.

    Voici le prototype de la fonction de la DLL pour un appel en C :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    int receiveMsg (char * buffer, int length, int * actualLength, char * eomChar, char * c1c2, long timeout)
    Cette fonction permet de récupérer une chaine dans buffer.
    -length est la taille de ce buffer
    -actualLength est un pointeur sur en entier, dans lequel doit être écrit la taille du message écrit dans buffer après excution de la fonction.
    -eomChar et et c1c2 sont 2 pointeurs sur des caractères (ce ne sont pas des chaines, ils contiennent tous 2 1 seul char)

    J'appelle cette fonction de la manière suivante sous Windev :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    nRes est un entier
     
    sfBufferLoc est une chaîne fixe sur 255
    nAdr est un entier = &sfBufferLoc
    nEomcharLoc est un entier sur 1 octet
    nC1c2Loc est un entier sur 1 octet
    nActualLengthLoc est un entier
    nLengthLoc est un entier = 255
    nTimeOutLoc est un entier = 50
     
     
    nRes = API(gsDll, "receiveMsg", &sfBufferLoc, nLengthLoc, &nActualLengthLoc, &nEomcharLoc, &nC1c2Loc, nTimeOutLoc)
    Je me suis référé à la page d'aide de Windev sur la conversion des types en C pour créer l'appel, mais ça ne fonctionne pas, à chaque fois j'ai "Une erreur système inattendue est survenue", et ça m'énerve ^^

    Voici le message d'exception complet :

    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
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
     
    Erreur à la ligne 30 du traitement Procédure globale ReceiveMsg.
    Une erreur système inattendue est survenue.
    Si cet incident se produit de manière systématique lorsque vous exécutez les mêmes manipulations, il est conseillé de transmettre au Support Technique Gratuit :
     - une description des circonstances de l'incident
     - les lignes de code, une fenêtre ou un projet permettant de reproduire le problème
     - les informations techniques suivantes
     
    Détails techniques :
     
    Module : WD110VM.DLL
    Version du module : 11.00Qd
    VI : 01F110054b
    Adresse de base : 25E60000
    Erreur système : Access violation (GPF)
    EIP = 25E6606D
    OS : Windows Longhorn (6.0.6000)
     
    Informations techniques
     
    Projet : Composant API
     
    Dump de l'erreur du module <WD110VM.DLL> <11.00Qd>.
     
    - Appel WL :
    Traitement de <TASharing.ReceiveMsg>, ligne <30>, thread <0>
     
    - Niveau : erreur fatale (EL_FATAL)
     
    - Code erreur : 1020
     
    - Code erreur WD55 : 0
     
    - Pas de code d'erreur système
     
    - Pas de message d'erreur système
     
    - Que s'est-il passé ?
    Une erreur système inattendue est survenue.
    Si cet incident se produit de manière systématique lorsque vous exécutez les mêmes manipulations, il est conseillé de transmettre au Support Technique Gratuit :
     - une description des circonstances de l'incident
     - les lignes de code, une fenêtre ou un projet permettant de reproduire le problème
     - les informations techniques suivantes
     
    Détails techniques :
     
    Module : WD110VM.DLL
    Version du module : 11.00Qd
    VI : 01F110054b
    Adresse de base : 25E60000
    Erreur système : Access violation (GPF)
    EIP = 25E6606D
    OS : Windows Longhorn (6.0.6000)
     
    - Infos de debug :
    Registres :
     
      EIP = 25E6606D    EBP = 0012F444
      EAX = 003D00F0    EBX = 01352D88
      ECX = 57203041    EDX = 00000006
      ESI = 01312D10    EDI = 01312D10
     
    Pile des appels :
     
    [WD110VM.DLL (25E60000), 11.00Qd, 01F110054b]	25E6606D
    [WD110VM.DLL (25E60000), 11.00Qd, 01F110054b]	25E74D90 : WL_SetParam() + 88731 bytes-> INVALID, stack increased by 4
    [???]	01312D10
    [WDTST.EXE (00000000), 11.00Al, 01F110053p]	74C08525
    Pile invalide
     
     
    - Infos attachées :
    EIT_DATEHEURE : 12/02/2008 13:07:39
    EIT_PILEWL :
    Procédure globale ReceiveMsg (TASharing.ReceiveMsg), ligne 30
    Clic sur BTN_receiveMsg (Fen_TestAPI.BTN_receiveMsg), ligne 10
     
    - Identifiant dans le .err : 1020
    Voilà, je suis vraiment bloqué à cause de ça, si vous avez une info, hésitez pas à répondre

    Merci d'avance !

  2. #2
    Inactif  
    Profil pro
    Inscrit en
    Février 2003
    Messages
    4 341
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 4 341
    Points : 5 953
    Points
    5 953
    Par défaut
    Déjà, il ne faut pas utiliser une chaine fixe, mais une chaine asciiz

    Ensuite, envoyer des entiers en lieu et place de caractères...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    nRes est un entier
     
    sfBufferLoc est une chaîne asciiz sur 255
    //nAdr est un entier = &amp;sfBufferLoc
    sEomcharLoc est une chaine asciiz sur 1
    sC1c2Loc est une chaine asciiz sur 1
    nActualLengthLoc est un entier
    nLengthLoc est un entier = 255
    nTimeOutLoc est un entier = 50
     
     
    nRes = API(gsDll, "receiveMsg", &amp;sfBufferLoc, nLengthLoc, &amp;nActualLengthLoc, &amp;cEomcharLoc, &amp;cC1c2Loc, nTimeOutLoc)
    Je ne sais pas si c'est la bonne formule, mais c'est ce que je ferais.

  3. #3
    Membre actif Avatar de peijnoob
    Profil pro
    Développeur informatique
    Inscrit en
    Août 2006
    Messages
    279
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 279
    Points : 294
    Points
    294
    Par défaut
    Je vais tester pour la chaîne asciiz, c'est peut-être ça.

    Par contre, pour le char, je suis sûr de mon coup ^^ Un char en C est simplement un entier sur 1 octet, et le type chaine ou même caractère de Windev ne correspond pas (Voir Conversion de type en C dans l'aide de Windev).

    Merci pour ta réponse, je vous tiens au jus ^^

  4. #4
    Membre actif Avatar de peijnoob
    Profil pro
    Développeur informatique
    Inscrit en
    Août 2006
    Messages
    279
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 279
    Points : 294
    Points
    294
    Par défaut
    Bon, j'ai testé encore plusieurs choses, dont ta solution.. Toujours la même erreur.

    Je me rappelle qu'avec un test hier, j'avais des erreurs système, non pas au moment de l'appel avec API, mais un peu plus tard dans le code (genre, a la fin de la fonction).

  5. #5
    Membre actif Avatar de peijnoob
    Profil pro
    Développeur informatique
    Inscrit en
    Août 2006
    Messages
    279
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 279
    Points : 294
    Points
    294
    Par défaut
    Oh là là, je suis complètement paumé là ><

    Après quelques tests supplémentaires, voilà que la fonction s'exécute sans erreur.

    Mais voilà mon appel :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    sfBufferLoc est une chaîne fixe sur 255
    nLengthLoc est un entier = 254
    nEomcharLoc est un entier sur 1 octet
    nC1c2Loc est un entier sur 1 octet
    nActualLengthLoc est un entier
    nTimeOutLoc est un entier = 50
     
    nRes = API(gsDll, "receiveMsg", sfBufferLoc, nLengthLoc, &nActualLengthLoc, &nEomcharLoc, &nC1c2Loc, nTimeOutLoc)
    1er constat, la chaine est fixe, et je passe directement la variable et pas son adresse (1er truc très louche)

    La fonction s'exécute, j'ai un nActualLengthLoc qui parait correct (79 caractères), jusque ici, tout va bien.

    Sauf que mon sfBufferLoc est vide.. Enfin, ça, ça me paraît logique étant donné que je lui passe directement la chaine au lieu de son adresse.

    Ce qui ne me parait pas logique en revanche, c'est que je n'ai pas de plantage lorsque je passe la chaîne, et on son adresse, à la fonction. Dans le code C, il attend un pointeur.

    Je suis vraiment paumé là :o

  6. #6
    Membre Expert

    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Juin 2003
    Messages
    4 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 506
    Points : 5 723
    Points
    5 723
    Par défaut
    Citation Envoyé par peijnoob Voir le message
    Bonjour à tous,


    Voici le prototype de la fonction de la DLL pour un appel en C :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    int receiveMsg (char * buffer, int length, int * actualLength, char * eomChar, char * c1c2, long timeout)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    nRes est un entier
     
    sfBufferLoc est une chaîne fixe sur 255
    nAdr est un entier = &sfBufferLoc
    nEomcharLoc est un entier sur 1 octet
    nC1c2Loc est un entier sur 1 octet
    nActualLengthLoc est un entier
    nLengthLoc est un entier = 255
    nTimeOutLoc est un entier = 50
     
     
    nRes = API(gsDll, "receiveMsg", &sfBufferLoc, nLengthLoc, &nActualLengthLoc, &nEomcharLoc, &nC1c2Loc, nTimeOutLoc)
    Les 2 avants-derniers paramètres tu passes des adresses d'entier(nEomcharLoc et nC1c2Loc) alors que le prototype dit qu'il attends l'adresse d'un char.

    donc soit tu les définis comme chaîne ASCII et tu ajoutes & devant pour fournir l'adresse ou alors tu les définis comme caractère (nEomcharloc est un caractère) et tu fournis également l'adresse avec & parce que toi tu envois l'adresse d'un entier et un entier ce n'est pas un char*

  7. #7
    Membre actif Avatar de peijnoob
    Profil pro
    Développeur informatique
    Inscrit en
    Août 2006
    Messages
    279
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 279
    Points : 294
    Points
    294
    Par défaut
    Citation Envoyé par hegros Voir le message
    Les 2 avants-derniers paramètres tu passes des adresses d'entier(nEomcharLoc et nC1c2Loc) alors que le prototype dit qu'il attends l'adresse d'un char.

    donc soit tu les définis comme chaîne ASCII et tu ajoutes & devant pour fournir l'adresse ou alors tu les définis comme caractère (nEomcharloc est un caractère) et tu fournis également l'adresse avec & parce que toi tu envois l'adresse d'un entier et un entier ce n'est pas un char*
    Encore une fois, le problème ne vient pas de là.

    J'ai réussi l'appel a la fonction, c'est juste que ma chaine buffer est vide.

    Encore une fois je rappelerai qu'en C un char est un entier sur 1 octet et qu'un char * est soit un pointeur sur ce char, soit une chaine de caractères (un pointeur vers tableau de char terminé par NULL)

    Ici, c'est le cas : le 1er paramètre est une chaine, et les 2 avant derniers paramètres sont des caractères, des entiers sur 1 octet quoi.

    Tiré de l'aide de Windev :

    Types simples en valeur de retour ou en paramètre d'entrée

    Type C | Commentaire C | Type WLangage
    char, int8 | 1 octet | entier sur 1 octet


    Types simples en paramètre de sortie

    Type C | Commentaire C | Type WLangage
    char*, int8* | 4 octets (en 32 bits) | &entier sur 1 octet
    Maintenant je capte pas pourquoi, quand je passe une chaine au lieu d'un pointeur sur ma chaine en 1er paramètre, ça ne plante pas mais ma chaîne est vide.

    Et comme je l'ai dit, j'ai testé pour les 2 avants derniers paramètres de mettre des chaînes, et ça ne fonctionne pas.

    La seule syntaxe qui ait marché, c'est celle de mon 2e post, mais mon buffer est toujours vide après l'appel de la fonction (alors que les autres paramètres sont bien renseignés)

  8. #8
    Membre Expert

    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Juin 2003
    Messages
    4 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 506
    Points : 5 723
    Points
    5 723
    Par défaut
    Ici, c'est le cas : le 1er paramètre est une chaine, et les 2 avant derniers paramètres sont des caractères, des entiers sur 1 octet quoi.
    Les 3 que tu cites sont du même types (char*) pourquoi tu ne passerais pas également l'adresse d'un entier pour le premier ?

    si tu passes l'adresse d'un entier et que la fonction l'utilise pour faire un strcmp ou strcpy il va se passer quoi ? (plantage)

    Ne connaissant pas le détail de l'implémentation de ta fonction C je préférerai respecter le prototype et ne pas faire d'hypothèse hasardeuze et fournir en paramètre des adresses sur des chaînes valides et pas sur des entiers

  9. #9
    Membre actif Avatar de peijnoob
    Profil pro
    Développeur informatique
    Inscrit en
    Août 2006
    Messages
    279
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 279
    Points : 294
    Points
    294
    Par défaut
    Bon bah au temps pour moi, j'ai de la ***** dans les yeux :o

    J'avais oublié un truc con : j'ai des sources en C qui utilisent cette API, et en m'y référant, j'ai vu ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    char eomChar[2]; 
    char c1c2[2];
    Donc mes 2 avant derniers paramètres ne sont pas des char simples mais bien des chaines

    J'ai corrigé mon code sous Windev qui me donne ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    nRes est un entier
    szBufferLoc est une chaîne ASCIIZ sur 2056
    szEomcharLoc est une chaîne ASCIIZ sur 2
    szC1c2Loc est une chaîne ASCIIZ sur 2
    nActualLengthLoc est un entier
    nLengthLoc est un entier = 2056
    nTimeOutLoc est un entier = 50
     
    nRes = API(gsDll, "receiveMsg", &szBufferLoc, nLengthLoc, &nActualLengthLoc, &szEomcharLoc, &szC1c2Loc, nTimeOutLoc)
    Seulement, quand je trace la chaine, elle est vide, et pourtant la taille indiquée est de 512 caractères, et je devrais avoir plein de trucs dedans ><

    EDIT : oubliez ce message, j'avais juste fait une petite boulette :o

    Merci pour votre aide !!

  10. #10
    Membre Expert

    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Juin 2003
    Messages
    4 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 506
    Points : 5 723
    Points
    5 723
    Par défaut
    tu parles de szBufferLoc ? normalement avec l'adresse la fonction peut la modifier.

    Montre le code source C de la fonction qui accède en écriture au premier paramètre, normalement en lui passant l'adresse d'une chaîne dans windev tu es censé récupérer les modifications faites dans la DLL

  11. #11
    Membre actif Avatar de peijnoob
    Profil pro
    Développeur informatique
    Inscrit en
    Août 2006
    Messages
    279
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 279
    Points : 294
    Points
    294
    Par défaut
    J'ai édit mon message au dessus, j'avais fait une boulette, ça marche bien ^^

    merci encore, la prochaine fois, je vérifierai mes sources

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

Discussions similaires

  1. Problème de fonction (paramètre)
    Par Tom4118 dans le forum Débuter
    Réponses: 4
    Dernier message: 01/12/2013, 18h30
  2. Réponses: 2
    Dernier message: 05/11/2010, 11h38
  3. Problème paramètre fonction pl/pgsql
    Par Nicoclem dans le forum Requêtes
    Réponses: 3
    Dernier message: 08/07/2009, 20h12
  4. Probléme sur las API MySql - fonction manquante
    Par boopix dans le forum C++Builder
    Réponses: 1
    Dernier message: 15/04/2007, 20h55
  5. Problème de paramètre fonction
    Par sone47 dans le forum MATLAB
    Réponses: 10
    Dernier message: 31/01/2007, 20h39

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