Le forum (ô combien francophone) des utilisateurs de Powerbuilder.
erreur système affichée au run du prg
erreur
Dernière modification par Sylvie de hannut (04-03-2014 14:52:49)
Hors ligne
Hum...
Vérifie que tu as bien défini 2 prototypes de fonctions externes comme MultiByteToWideChar et WideCharToMultiByte et pas multibytetowidechar ou MuLtIByTeToWiDECHar. C'est important, sinon ça risque de planter...
Hors ligne
Global external function :
function ulong MultiByteToWideChar(ulong CodePage, ulong dwflags, ref string lpmultibytestr, ulong cchmultibyte, ref blob lpwidecharstr, ulong cchwidechar) library "kernel32.dll"
function ulong WideCharToMultiByte(ulong CodePage, ulong dwFlags, ref blob lpWideCharStr, ulong cchWideChar, ref string lpMultiByteStr, ulong cbMultiByte, ref string lpUsedDefaultChar, ref boolean lpUsedDefaultChar) library "kernel32.dll"
J'ai fait un copier-coller de ton code
Dernière modification par Sylvie de hannut (04-03-2014 15:09:03)
Hors ligne
le "linking reference" m'intrigue... Est ce que cette fonction globale est dans une PBL commune à plusieurs projets ?
Hors ligne
oui, c'est exact, elle est liée à deux projets.
Je creuse plus loin, merci :-)
Hors ligne
Sylvie de hannut a écrit:
oui, c'est exact, elle est liée à deux projets.
Je crois que c'est la cause du "unresolved external" un peu comme quand on ajoute ou modifie la signature de méthodes dans un objet et qu'on exécute le projet sans tout rebuilder.
Dans mon exemple, la fonction était dans une fenêtre et les prototypes étaient locaux à la fenêtre. Tu devrais placer les prototypes directement dans la fonction globale pour que les déclarations soient accessible directement dans la fonction globale.
Si tu veux copier directement la déclaration des external dans ta fonction, copie les 4 lignes "type prototypes".."end protoypes" au début de la fontion dans ta fonction globale entre le end type de la ligne 2 et le forward prototype de la ligne 4 en allant dans "edit source"
Le code de la fonction devient :
global type utf8_to_ansi from function_object end type //=============< ICI on ajoute les local externals >================================ type prototypes function ulong MultiByteToWideChar(ulong CodePage, ulong dwflags, ref string lpmultibytestr, ulong cchmultibyte, ref blob lpwidecharstr, ulong cchwidechar) library "kernel32.dll" function ulong WideCharToMultiByte(ulong CodePage, ulong dwFlags, ref blob lpWideCharStr, ulong cchWideChar, ref string lpMultiByteStr, ulong cbMultiByte, ref string lpUsedDefaultChar, ref boolean lpUsedDefaultChar) library "kernel32.dll" end prototypes //==============< fin des local externals >====================================== forward prototypes global function string utf8_to_ansi (string as_utf8) end prototypes global function string utf8_to_ansi (string as_utf8); //conversion utf-8 -> ansi //utilisation d'une chaîne native windows en wide-char comme pivot constant ulong CP_ACP = 0 constant ulong CP_UTF8 = 65001 string ls_wide, ls_ansi, ls_null blob lbl_wide ulong ul_len boolean lb_flag setnull(ls_null) lb_flag = false //on détermine la longueur de la chaine utf-8 convertie en wide-char setnull(lbl_wide) ul_len = multibytetowidechar(CP_UTF8, 0, as_utf8, -1, lbl_wide, 0) //on alloue la place pour que windows puisse écrire dedans ls_wide = space(ul_len * 2) lbl_wide = blob(ls_wide) //conversion utf-8 -> wide char ul_len = multibytetowidechar(CP_UTF8, 0, as_utf8, -1, lbl_wide, ul_len) //on détermine la longueur finale de la chaine ansi setnull(ls_ansi) ul_len = widechartomultibyte(CP_ACP, 0, lbl_wide, -1, ls_ansi, 0, ls_null, lb_flag) //on alloue la chaine pour que windows puisse écrire dedans ls_ansi = space(ul_len) //conversion wide-char -> ansi ul_len = widechartomultibyte(CP_ACP, 0, lbl_wide, -1, ls_ansi, ul_len, ls_null, lb_flag) return ls_ansi end function
Dernière modification par seki (04-03-2014 17:10:44)
Hors ligne
Merci beaucoup, je viens de faire les modifications
Je teste tout ça demain
Parce que maintenant moi
Bonne soirée à tous
Bonne nuit
Et encore un très grand
Hors ligne
Derniers échos : la fonction marche à merveille.
Mais, j'ai vu que dans la suite du traitement qu'on retriture le fichier en changeant le codage de UTF-16 à iso-8859-1, ce qui me rebousille le fichier :-( :-( :-(
ls_work = '' ld_return = FileOpen(ls_fichier_txt+'SND.XML',LineMode!,Read!) ld_file_in = ld_return DO UNTIL ld_return < 0 ld_return = FileRead(ld_file_in,ls_return) IF ld_return >= 0 THEN ls_work+= ls_return END IF LOOP FileClose(ld_file_in) // trafiquer le xml : ls_work = f_global_replace(ls_work,'§',' ') // - pour ne pas tronquer les derniers espaces ls_work = f_global_replace(ls_work,'XxMmLl','XML') // - parce que le nom ne peut pas commencer par (ni être) XML ls_work = f_global_replace(ls_work,'xXmMlL','xml') // GAR 167401 : pour avoir en minuscule plutot qu'en majuscule ls_work = f_utf8_to_ansi(ls_work) // nouvelle fonction iubs_interface.istr_downloadfiles[1].filename = ls_work ls_xml_a_envoyer = ls_work IF iubs_interface.istr_downloadfiles[1].filename = '' THEN iubs_interface.istr_downloadfiles[1].xmlcontent = '' MessageBox(uf_lib_langue('Attention - pas envoyé|Opgelet - niet gestuurd'),& uf_lib_langue('Impossibilité sauvetage demande : vérifier existence répertoire et accessibilité svp'),Exclamation!,Ok!,1) ELSE IF uf_nvl(iubs_interface.is_com_recup) <> '' THEN ls_work = iubs_interface.iu_carrefourcompbni_service.indentxml(ls_work) ls_work = f_global_replace(ls_work,'utf-16','iso-8859-1') ld_return = FileOpen(ls_fichier_txt+'SND.XML',StreamMode!,Write!,LockWrite!,Replace!) DO WHILE LEN(ls_work) > 0 FileWrite(ld_return,ls_work) ls_work = MID(ls_work,32766) LOOP FileClose(ld_return) END IF
J'ai essayé en mettant la fonction après cette boucherie, mais là ça ne va pas car je ne pars pas du bon codage.
ls_work = '' ld_return = FileOpen(ls_fichier_txt+'SND.XML',LineMode!,Read!) ld_file_in = ld_return DO UNTIL ld_return < 0 ld_return = FileRead(ld_file_in,ls_return) IF ld_return >= 0 THEN ls_work+= ls_return END IF LOOP FileClose(ld_file_in) // trafiquer le xml : ls_work = f_global_replace(ls_work,'§',' ') // - pour ne pas tronquer les derniers espaces ls_work = f_global_replace(ls_work,'XxMmLl','XML') // - parce que le nom ne peut pas commencer par (ni être) XML ls_work = f_global_replace(ls_work,'xXmMlL','xml') // GAR 167401 : pour avoir en minuscule plutot qu'en majuscule iubs_interface.istr_downloadfiles[1].filename = ls_work IF iubs_interface.istr_downloadfiles[1].filename = '' THEN iubs_interface.istr_downloadfiles[1].xmlcontent = '' MessageBox(uf_lib_langue('Attention - pas envoyé|Opgelet - niet gestuurd'),& uf_lib_langue('Impossibilité sauvetage demande : vérifier existence répertoire et accessibilité svp'),Exclamation!,Ok!,1) ELSE IF uf_nvl(iubs_interface.is_com_recup) <> '' THEN ls_work = iubs_interface.iu_carrefourcompbni_service.indentxml(ls_work) ls_work = f_global_replace(ls_work,'utf-16','iso-8859-1') ls_work = f_utf8_to_ansi(ls_work) // nouvelle fonction ls_xml_a_envoyer = ls_work ld_return = FileOpen(ls_fichier_txt+'SND.XML',StreamMode!,Write!,LockWrite!,Replace!) DO WHILE LEN(ls_work) > 0 FileWrite(ld_return,ls_work) ls_work = MID(ls_work,32766) LOOP FileClose(ld_return) END IF
Rebelotte à la récupération de la réponse, où on modifie le codage, également en iso-8859-1.
Si je change la constante UTF8 avec la valeur de la constant iso-8859-1, ça peut marcher ?
Merci
Dernière modification par Sylvie de hannut (05-03-2014 09:59:04)
Hors ligne
les anglais ont une expression pour ça : "code smells" (en gros, ce code pue
)
Sylvie de hannut a écrit:
Rebelotte à la récupération de la réponse, où on modifie le codage, également en iso-8859-1.
Si je change la constante UTF8 avec la valeur de la constant iso-8859-1, ça peut marcher ?
Je n'en sais rien, je ne sais pas à quoi vous espérez arriver et en partant de quoi.
Déjà on convertit du texte censé être en utf-8 vers ansi (soit plus ou moins l'encodage natif de windows) mais ensuite
f_global_replace(ls_work,'utf-16','iso-8859-1')
Va "patcher" l'encodage de ce xml pour faire croire que c'est du latin1 (=iso-8859-1) qui n'est pas la même chose que ansi, notamment les accents ne sont pas tous au même endroit et le latin1 ne contient pas l'euro (c'est le latin9 = iso-8859-15 qui a l'euro et pas au même endroit : à la place du '¤' du latin1)...
Sais tu pourquoi les données xml de départ sont triturées à ce point et quel est but à atteindre ?
On dirait des tentatives de bricolage pour faire "tomber en marche" le truc sans comprendre précisément le fonctionnement...
Et un truc qui me choque au passage :
DO WHILE LEN(ls_work) > 0 FileWrite(ld_return,ls_work) ls_work = MID(ls_work,32766) LOOP
Au premier tour de boucle, on écrit tout ls_work, ensuite tant qu'il en reste on tronque à chaque fois les premiers 32k et on écrit tout le reste... Les données écrites seront donc répétées avec de moins en moins de texte au début.
C'est du code testé ça, où vous n'avez jamais eu le cas où les données faisaient plus de 32 k ?
Edit: je viens de voir que FileWrite est aussi limité à écrire 32766 octets. Ceci dit au lieu de réallouer la chaîne en boucle, on peut aussi travailler sur la chaîne de départ sans réallouer avec un mid() qui précise la longueur en utilsant le retour de FileWrite pour savoir de combien décaller la "fenêtre" sur les données à écrire...
Dernière modification par seki (05-03-2014 13:12:06)
Hors ligne