Le forum (ô combien francophone) des utilisateurs de Powerbuilder.
Bonjour,
Nous avons intégré à notre application développée en Powerbuilder 9 des appels d'API. Les diverses fonctions sont appelées successivement.
Open -> Génère un thread
<traitements divers>
Close -> Fermeture du thread
Shutdown -> Kill du thread
Mais l'application se termine en exception win32 non gérée avec les codes suivants (au hasard, jamais les mêmes...) : 3108, 3144, 3944, 2868, 4724, 3696, 1016...
Parfois l'application plante après l'appel d'une des fonctions de l'api.
Les dysfonctionnements apparaissent tant en interprêté qu'en compilé. En interprêté parfois même, cela plante alors que je suis revenu dans l'environnement de développement et que je travaille sur mon écran où les fonctions sont appelées...
Dernière modification par sbouvetJD (10-05-2010 09:57:17)
Hors ligne






Bonjour,
Il m'apparait difficile de t'apporter une réponse avec aussi peu de détails sur un sujet aussi vaste.
Il est peut être plus simple de gérer le multithread à l'aide des fonctions natives de PB : SharedObject...
Hors ligne
La bibliothèque en question est un module de contrôle et normalisation d'adresse de la société EXPERIAN / QAS.
Apparemment ce n'est pas tant l'appel des fonctions qui pose problème qu'un "truc" qui doit traîner en mémoire...
Voici succintement un bout de code :
ll_ret = QA_Open("", "", QAS_Handle) If QAS_Handle = 0 Then ll_ret = QA_Close(QAS_Handle) QA_Shutdown() FileClose(li_file) Return 1 End If /* SELECTION DU FICHIER DE DONNEES (PAR DEFAUT) */ ll_ret = QA_SetActiveData(QAS_Handle, "") /* SELECTION DU MODE DE SAISIE */ ll_ret = QA_SetEngine(QAS_Handle, qaengine_SINGLELINE) /* SELECTION DU FORMAT DE SAISIE */ ll_ret = QA_SetActiveLayout(QAS_Handle, "JD97Client") If isNull(dw_1.getItemString(ll_row, "num_voie")) Then lsa_element[1] = "" Else lsa_element[1] = dw_1.getItemString(ll_row, "num_voie") If isNull(dw_1.getItemString(ll_row, "nom_voie")) Then lsa_element[2] = "" Else lsa_element[2] = dw_1.getItemString(ll_row, "nom_voie") If isNull(dw_1.getItemString(ll_row, "code_postal")) Then lsa_element[3] = "" Else lsa_element[3] = dw_1.getItemString(ll_row, "code_postal") If isNull(dw_1.getItemString(ll_row, "ville")) Then lsa_element[4] = "" Else lsa_element[4] = dw_1.getItemString(ll_row, "ville") ls_adresse = lsa_element[4] + "," + lsa_element[3] + "," + lsa_element[2] + "," + lsa_element[1] /* RECHERCHE A PARTIR DE LA CHAINE D'ADRESSE CONCATENEE */ ll_ret = QA_Search(QAS_Handle, ls_adresse) /* RETOURNE L'ETAT DE LA RECHERCHE */ ll_ret = QA_GetSearchStatus(QAS_Handle, ll_nb_resultat, ll_temp, ll_etat) /* PARCOURS DES RESULTATS DE LA RECHERCHE */ If il_retour = 0 Then For i = 0 To ll_nb_resultat - 1 ll_ret = QA_GetResult(QAS_Handle, i, ls_adresse, QAS_LONGUEUR_ADRESSE, ll_pertinence, ll_retour) If ll_ret >= 0 Then ll_ret = QA_EndSearch(QAS_Handle) ll_ret = QA_Close(QAS_Handle) QA_Shutdown() FileClose(li_file) Return 1 End If lb_1.addItem(String(i) + "~t" + gf_qas_null_car(ls_adresse)) Next /* S'IL Y A PLUSIEURS RESULTATS, DEMANDER A L'UTILISATEUR DE CHOISIR */ If ll_nb_resultat > 1 Then MessageBox("Test", , Information!) ll_retour = -1 ElseIf ll_nb_resultat = 1 Then /* TRAITEMENT DE LA LIGNE */ ll_retour = 0 Else /* AUCUNE CORRESPONDANCE */ If MessageBox("Test", "Aucune correspondance d'adresse, voulez-vous corriger ?", Question!, YesNo!, 1) = 1 Then FileClose(li_file) Return 1 End If End If Else ll_retour = il_retour End If /* ON FORMATE L'ADRESSE SELECTIONNEE */ If ll_retour >= 0 Then ll_ret = QA_FormatResult(QAS_Handle, ll_retour, "", ll_nb_resultat, ll_etat) For i = 0 To ll_nb_resultat - 1 ll_ret = QA_GetFormattedLine(QAS_Handle, i, ls_adresse, QAS_LONGUEUR_ADRESSE, ls_type, QAS_LONGUEUR_ADRESSE, ll_etat) Choose Case i Case 0 /* 1E LIGNE ADRESSE */ If dw_1.getItemString(ll_row, "adresse") = "" Then dw_1.setItem(ll_row, "adresse", ls_adresse) Case 1 /* NUMERO VOIE */ dw_1.setItem(ll_row, "num_voie", ls_adresse) Case 2 /* NOM VOIE */ dw_1.setItem(ll_row, "nom_voie", ls_adresse) Case 3 /* BOITE POSTALE */ dw_1.setItem(ll_row, "bp", ls_adresse) Case 4 /* CODE POSTAL */ dw_1.setItem(ll_row, "code_postal", ls_adresse) Case 5 /* VILLE */ dw_1.setItem(ll_row, "ville", ls_adresse) End Choose Next End If ll_ret = QA_EndSearch(QAS_Handle) ll_ret = QA_Close(QAS_Handle) QA_Shutdown()
Hors ligne






Bonjour,
Il est très difficile de t'apporter une réponse ne sachant pas ce qui se passe dans les fonctions de QA_...
A priori, ils contiennent des fonctions réalisant des appels API externes.
Lorsque tu fais appel à des fonctions de l'API avec des pointeurs chaînes, il ne faut pas oublier d'initialiser les pointeurs pour leur attribuer l'espace nécessaire sinon tu as exactement le comportement que tu nous expliques.
C'est à dire que si tu attends en retour une chaîne de longueur 255, tu dois préalablement réaliser cette opération avant d'invoquer la fonction de l'API pour réserver l'espace au pointeur :
string ls_adresse
ls_adresse = space(255)
MyAPIFonction(ls_adresse)
Hors ligne
C'est exacteement ça ! J'ai eu la réponse ce vendredi. Merci beaucoup, je ne savais point. Mais l'ignorance est une force et je suis super fort !
Hors ligne