Novembre 2024 | Lun | Mar | Mer | Jeu | Ven | Sam | Dim |
---|
| | | | 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 | | Calendrier |
|
|
| Je n'arrive pas à faire passer mon string par ma DLL | |
| | Auteur | Message |
---|
papydall
Nombre de messages : 7017 Age : 74 Localisation : Moknine (Tunisie) Entre la chaise et le clavier Date d'inscription : 03/03/2012
| Sujet: Je n'arrive pas à faire passer mon string par ma DLL Lun 16 Juil 2012 - 20:32 | |
| Salut tout le monde. @Tous ceux qui peuvent me répondre : merci d’avance. Je suis en train de coder une DLL en DELPHI 6, dont la fonction devrait retourner une chaine de caractères calculée en fonction d’un nombre entier transmis par référence. Le test de la DLL n’est pas satisfaisant et déclenche 2 erreurs. Pour vous donner une idée précise du problème, voici une adaptation du source (en DELPHI) de la DLL ; un programme-test en Panoramic et les 2 copies d’écran des erreurs. Code DELPHI : ai-je commis une erreur dans ce code? - Code:
-
library MaDLL;
uses ShareMem,math;
{$R *.res}
{ ---------------------------------------------------------- } function MaFonction(n: int64): string; var s : string; begin { Ici, les instructions qui vont construire la chaine de caractères en fonction du paramètre n du type int64. En effet, il s'agit d'un entier assez long (au moins 12 chiffres). Par exemple : le contenu de s est : }
s := 'Ceci est un test de ce que pourrait être le contenu de la chaine'; s := s + ' de caracteres que doit retourner au programme appellant '; s := s + '(en Panoramic), la fonction MaFonction. ' ; s := s + 'Cette chaine pourrait contenir plus de 255 caractères'; MaFonction := s; result := s;
end;
{ ------------------------------------------------------------------ } function TestMaFonction(var value: Extended; var Sortie : string): integer; stdcall;
begin sortie := MaFonction(Trunc(Value)); result := 0; end;
exports TestMaFonction; end.
Code PANORAMIC - Code:
-
dim value,Sortie$, i% width 0,1000 memo 1 :width 1, 980 dll_on "MaDLL.dll" value = 1234567890987654321 sortie$ = string$(255," ") i% = dll_call2("TestMaFonction", adr(Value), adr(Sortie$)) item_add 1,sortie$ dll_off
1ere erreur en exécutant le programme Panoramic 2eme erreur après avoir appuyé sur OK et fermé PANORAMIC Merci pour votre attention A+ j'ai édité le programme en PANORAMIC La 2eme erreur a disparu
Dernière édition par papydall le Lun 16 Juil 2012 - 22:47, édité 1 fois | |
| | | Yannick
Nombre de messages : 8635 Age : 53 Localisation : Bretagne Date d'inscription : 15/02/2010
| Sujet: re Lun 16 Juil 2012 - 21:39 | |
| As tu essayé de couper la ficelle.... heu....le string... Oui bon , de diminuer le nbre de caracteres.... Edit : desolé , c'était trop tentant .... | |
| | | papydall
Nombre de messages : 7017 Age : 74 Localisation : Moknine (Tunisie) Entre la chaise et le clavier Date d'inscription : 03/03/2012
| Sujet: Re: Je n'arrive pas à faire passer mon string par ma DLL Lun 16 Juil 2012 - 21:51 | |
| J’ai modifié la DLL : la chaine de sortie ne contient que le mot ‘Bonjour’ La 1ere erreur est toujours présente mais il n’y a plus de 2eme erreur !
| |
| | | Yannick
Nombre de messages : 8635 Age : 53 Localisation : Bretagne Date d'inscription : 15/02/2010
| Sujet: re Lun 16 Juil 2012 - 22:09 | |
| Jean debord m'a écris dans un post de formater ma variable $ avant l'appelle de la dll
celà te donnerai
Sortie$=string$( Nbre de caracteres, " ")
il y a un espace entre les guillemets | |
| | | papydall
Nombre de messages : 7017 Age : 74 Localisation : Moknine (Tunisie) Entre la chaise et le clavier Date d'inscription : 03/03/2012
| Sujet: Re: Je n'arrive pas à faire passer mon string par ma DLL Lun 16 Juil 2012 - 22:52 | |
| j'ai édité le programme en PANORAMIC La 2eme erreur a disparu mais la 1ere erreur se manifeste toujours bien que la sortie semble correcte. | |
| | | Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
| Sujet: Re: Je n'arrive pas à faire passer mon string par ma DLL Lun 16 Juil 2012 - 23:32 | |
| Pour passer une chaîne de caractères à une DLL en Delphi 6, je fais comme ceci: - Code:
-
function MaFonction(chaine: pchar): integer; stdcall; export; var MaChaine: string; begin MaChaine:= pchar(pstring(chaine)^); ...
Et en Panoramic, je l'appelle comme ceci: - Code:
-
dim s$, res% s$ = "Ma chaîne de caractères pour ma DLL" res% = dll_call1("MaFoncton",adr(s$))
Pour recevoir en Panoramic un résultat sous forme de chaîne de caractères, je fais comme ceci: - Code:
-
function MaFonctionBis(s: integer): integer; stdcall; export; var txt: string; begin txt := 'Mon résultat en chaîne de caractères à retourner à Panoramic'; CopyTextToPanoramic(integer(@txt), 0, s); result := 0; end; avec la mention du module suivant dans les clauses USES: - Code:
-
TextToPanoramic in 'TextToPanoramic.pas';
et ce moduleTextToPanoramic.pas a le source suivant: - Code:
-
unit TextToPanoramic; { Cette unité contient la procédure CopyTextToPanoramic(source,offset,destination); source et destination sont des pointeurs sur des strings Panoramic ou des PChar en Delphi. offset est le décalage à partir duquel on écrit dans la destination ( 0 signifie depuis le début). La copie s'arrêtre automatiquement dès que la fin d'un des strings est rencontré. }
interface procedure CopyTextToPanoramic(inp, offs, out:integer); stdcall;
implementation
procedure CopyTextToPanoramic(inp, offs, out:integer); stdcall; var xout,yinp: pchar; n: integer; begin xout := pchar(pstring(out)^); yinp := pchar(pstring(inp)^); if offs>0 then begin for n:=1 to offs do begin inc(xout); if (xout^ = #0) then exit { sortir si l'offset va à la fin} end end; while (xout^ <> #0) and (yinp^ <> #0) do begin xout^ := yinp^; inc(xout); inc(yinp); end; end;
end. En en Panoramic, je l'appelle comme ceci: - Code:
-
dim s$,res% s$ = string$(255," ") res% = dll_call1("MaFonctionBis",adr(s$) message "Le résultat est: "+s$
| |
| | | papydall
Nombre de messages : 7017 Age : 74 Localisation : Moknine (Tunisie) Entre la chaise et le clavier Date d'inscription : 03/03/2012
| Sujet: Re: Je n'arrive pas à faire passer mon string par ma DLL Lun 16 Juil 2012 - 23:47 | |
| Salut klaus Merci pour ton intervention. je vais étudier ta proposition et je te tiens au courant. | |
| | | papydall
Nombre de messages : 7017 Age : 74 Localisation : Moknine (Tunisie) Entre la chaise et le clavier Date d'inscription : 03/03/2012
| Sujet: Re: Je n'arrive pas à faire passer mon string par ma DLL Mar 17 Juil 2012 - 5:57 | |
| @Klaus. Si ce n’est pas trop te demander, je te remercie d’avance de bien vouloir consacrer un peu de ton temps pour corriger ce que je n’arrive pas à le faire. Voici le source de ma DLL - Code:
-
library Chiffres2Lettres;
{ cette DLL transforme un nombre en chiffres en un nombre en lettres de 0 à 99 999 999 999 999 999,99 c-a-d de zero à quatre-vingt dix-neuf billiards neuf cent quatre-vingt dix-neuf billions neuf cent quatre-vingt dix-neuf milliards neuf cent quatre-vingt dix-neuf millions neuf cent quatre-vingt dix-neuf mille neuf cent quatre-vingt dix-neuf virgule quatre-vingt dix-neuf }
uses Math; //necessaire pour les fonctions mathématiques log10, power etc.. { =============================================================================} function NombreEnLettres(nombre: int64): string; export; var d, n2 : int64; s : string[1]; const Chiffres : array[0..19] of string = ('' , 'un' , 'deux' , 'trois' , 'quatre' , 'cinq' , 'six' , 'sept' , 'huit' , 'neuf' , 'dix' , 'onze' , 'douze' , 'treize' , 'quatorze' , 'quinze' , 'seize' ,'dix-sept' , 'dix-huit' , 'dix-neuf'); Dizaines : array[2..9] of string = ('vingt' , 'trente' , 'quarante' , 'cinquante' , 'soixante' , '' , 'quatre-vingt' , ''); PuissancesMille : array[1..6] of string = ('mille', 'million', 'milliard', 'billion', 'billiard', 'trillion'); // etc... begin CASE nombre of 0..19: result := Chiffres[nombre]; // fin 20..69,80..89: if ((nombre mod 10 = 1) and (nombre <> 81)) then result := Dizaines[nombre div 10] + ' et ' + NombreEnLettres(nombre mod 10) else // on dit trente et un mais quatre-vingt un ! result := Dizaines[nombre div 10] + ' ' + NombreEnLettres(nombre mod 10); 70..79,90..99: if (nombre = 71) then // 71 = 'soixante' et onze ! result := Dizaines[nombre div 10 -1] + ' et ' + NombreEnLettres(nombre mod 10 +10) else result := Dizaines[nombre div 10 -1] + ' ' + NombreEnLettres(nombre mod 10 +10); 100..999: if (nombre div 100 =1) then // on ne dit pas un cent ! result := 'cent' + ' '+ NombreEnLettres(nombre mod 100) else begin if (nombre mod 100)=0 then s := 's' else s := ''; result := Chiffres[nombre div 100]+' '+'cent' + s + ' '+ NombreEnLettres(nombre mod 100); end; else begin { ex: 10^6 = 1M <=> exp (6 x ln(10) = 1M <=> 6 x ln(10) = ln (1M) <=> 6 = ln(1M) / ln(10) = Log10 (1M) } d := trunc(log10(nombre)) div 3; // arrondir puiss. 10 n2 := trunc(power(10 , d * 3)); // vers groupe puissances de 1000 +proche if (trunc(log10(nombre))=3) and (trunc(nombre/1000)=1) then // on ne dit pas un mille ! result := PuissancesMille[d] + ' ' + NombreEnLettres(nombre mod n2) else begin if d=1 then s := '' else s := 's'; // s au pluriel sauf mille ! result := NombreEnLettres(nombre div n2) + ' ' + PuissancesMille[d] + s + ' ' + NombreEnLettres(nombre mod n2); end; end; END; { case } if result = '' then result := 'zero'; end; { =============================================================================} function NbEnLettres(var montant: Extended; var somme : string): integer; stdcall; export; begin somme := NombreEnLettres(Trunc(montant)); somme := somme + ' virgule ' + NombreEnLettres(round(100 * frac(montant))); result := 0; end; { =============================================================================} exports NombreEnLettres, NbEnLettres; end.
La compilation de la DLL est correcte. Et voici le programme Panoramic qui fait l’appel - Code:
-
dim montant,Somme$, i% width 0, 1000 dll_on "Chiffres2Lettres.dll" montant = 123456789.12 ' somme$ = string$(255," ") i% = dll_call2("NbEnLettres", adr(montant), adr(Somme$)) print Somme$ dll_off
Le resultat est décevant. J’ai beau essayer comme tu l’as indiqué mais en vain ! Je n’ai pas bien saisis le transfert d’une chaine de caractères entre la DLL et l’appelant. Sans vouloir te jeter des fleurs, je te remercie vivement de ta disponibilité à apporter ton aide à tous et je te félicite pour ton immense savoir. Bien que, toi et moi, nous ayons à peu près le même âge, je suis ravi d’être ton élève ! | |
| | | jean_debord
Nombre de messages : 1266 Age : 70 Localisation : Limoges Date d'inscription : 21/09/2008
| Sujet: Re: Je n'arrive pas à faire passer mon string par ma DLL Mar 17 Juil 2012 - 8:44 | |
| Dans la fonction : - Code:
-
function NombreEnLettres(nombre: int64): string; export;
Il manque le stdcall, et je pense qu'on ne peut pas passer des entiers de 64 bits en Panoramic, seulement des entiers de 32 bits ? Et dans la fonction : - Code:
-
function NbEnLettres(var montant: Extended; var somme : string): integer; stdcall; export;
je pense qu'on ne peut pas passer le type Extended non plus, seulement le type Double ? Par ailleurs , les fonctions ne peuvent retourner que des entiers, et les chaînes de caractères doivent être passées sous forme de pointeurs sur des chaînes à zéro termical, soit ZSTRING PTR en FreeBasic et PCHAR en Delphi. | |
| | | Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
| Sujet: Re: Je n'arrive pas à faire passer mon string par ma DLL Mar 17 Juil 2012 - 10:06 | |
| J'ai fait une version de démonstration de ta DLL pour renvoyer une chaine de caractères, tout en prenant un entier en entrée: - Code:
-
library Chiffres2Lettres;
{ cette DLL transforme un nombre en chiffres en un nombre en lettres de 0 à 99 999 999 999 999 999,99 c-a-d de zero à quatre-vingt dix-neuf billiards neuf cent quatre-vingt dix-neuf billions neuf cent quatre-vingt dix-neuf milliards neuf cent quatre-vingt dix-neuf millions neuf cent quatre-vingt dix-neuf mille neuf cent quatre-vingt dix-neuf virgule quatre-vingt dix-neuf }
uses Math, SysUtils, TextToPanoramic in 'TextToPanoramic.pas';
//necessaire pour les fonctions mathématiques log10, power etc.. { =============================================================================} function NombreEnLettres(nombre, txt: integer): integer, stdcall; export; var sresult: string;
begin if nombre>0 then sresult := IntToStr(nombre); if sresult = '' then sresult := 'zero'; CopyTextToPanoramic(integer(@sresult), 0, txt); retulr := 0; end; { =============================================================================} exports NombreEnLettres; end.
Cela retourne le nombre en chaîne de caractères (certes numériques), ou le mot "zéro". Ceci pour montrer comment on retourne des strings vers Panoramic. Jean-Debord a parfaitement relevé les anomalies dans ta DLL. Pour les entiers: Panoramic ne connait que les variables déclarées par "dim x%". En Delphi, in faut les déclarer "integer", pas autre chose. Pour les flottants: Tu ne peux les passer que par adresse, de la manière suivante: - Code:
-
dim valeur, res% valeur = 4*atn(1) : ' pi res% = dll_call1("MaFonction",adr(valeur))
et en Delphi, il faut que tu récupères cela en utilisant le param_tre (déclaré en integer) comme un pointeur. | |
| | | papydall
Nombre de messages : 7017 Age : 74 Localisation : Moknine (Tunisie) Entre la chaise et le clavier Date d'inscription : 03/03/2012
| Sujet: Re: Je n'arrive pas à faire passer mon string par ma DLL Mar 17 Juil 2012 - 12:10 | |
| @jean_debord et Klaus
Vous êtes très gentils, merci pour vos interventions. Le stdcall je le connais, il a du être perdu lors de la mise au point du programme !
Pour les autres remarques, j’en tiendrais compte. Je vais revoir ma copie pour faire aboutir ma DLL. J’y arriverais certainement et c’est grâce à vous.
A+
| |
| | | Contenu sponsorisé
| Sujet: Re: Je n'arrive pas à faire passer mon string par ma DLL | |
| |
| | | | Je n'arrive pas à faire passer mon string par ma DLL | |
|
Sujets similaires | |
|
| Permission de ce forum: | Vous ne pouvez pas répondre aux sujets dans ce forum
| |
| |
| |