FORUM DE DISCUSSION SUR LE LANGAGE PANORAMIC

Développement d'applications avec le langage Panoramic
 
AccueilAccueil  FAQFAQ  RechercherRechercher  S'enregistrerS'enregistrer  MembresMembres  GroupesGroupes  Connexion  
Derniers sujets
» Planétarium virtuel.
par Pedro Alvarez Hier à 16:57

» Roues dentées
par jean_debord Hier à 10:40

» Attention arnaque !
par mindstorm Jeu 19 Juil 2018 - 19:18

» Qui fait quoi ?
par silverman Mer 18 Juil 2018 - 15:21

» ITEM_SELECT N,L pour synedit
par silverman Mer 18 Juil 2018 - 15:20

» Boussole
par jean_debord Mer 18 Juil 2018 - 11:06

» Roue à n faces
par Marc Dim 15 Juil 2018 - 22:16

» Exemple d'une nouvelle version d'un GRID
par Jean Claude Ven 13 Juil 2018 - 10:32

» Une simple question
par Oscaribout Sam 7 Juil 2018 - 23:20

» BUG sur l'objet TAB
par Jack Sam 7 Juil 2018 - 21:12

» Monopoly moderne
par jjn4 Sam 7 Juil 2018 - 15:06

» Récapitulatif ludothèque panoramic jjn4
par jjn4 Ven 6 Juil 2018 - 17:41

» Lignes ondulées
par JL35 Ven 6 Juil 2018 - 17:39

» bug off_activate 0 : sans d'effet
par silverman Ven 6 Juil 2018 - 13:02

» Position des objets d'un conteneur dans FBPano et Panoramic
par Navigateur Ven 6 Juil 2018 - 12:59

Navigation
 Portail
 Index
 Membres
 Profil
 FAQ
 Rechercher
Rechercher
 
 

Résultats par :
 
Rechercher Recherche avancée
Juillet 2018
LunMarMerJeuVenSamDim
      1
2345678
9101112131415
16171819202122
23242526272829
3031     
CalendrierCalendrier

Partagez | 
 

 ADR_STRING(V)

Aller en bas 
AuteurMessage
silverman

avatar

Nombre de messages : 659
Age : 46
Localisation : Picardie
Date d'inscription : 18/03/2015

MessageSujet: ADR_STRING(V)   Ven 9 Fév 2018 - 18:08

Il n'existe pas de moyen pour transmettre/recevoir une chaine de caractère à/d' une dll, puisque l'adresse d'une chaine transmise par la fonction ADR n'est pas la bonne. Il ne sera pas possible de créer une FNC pour remédier à cela à cause de l'allocation dynamique de la mémoire.
Cette fonction permettrait de résoudre ce pb.
Revenir en haut Aller en bas
Voir le profil de l'utilisateur
Jack
Admin
avatar

Nombre de messages : 1868
Date d'inscription : 28/05/2007

MessageSujet: Re: ADR_STRING(V)   Ven 9 Fév 2018 - 18:26

silverman a écrit:
l'adresse d'une chaine transmise par la fonction ADR n'est pas la bonne.

Que veux-tu dire par là ?

Le sujet des adresses de chaînes de caractères est vaste.
Il y a des chaines de caractères terminées par la valeur 0, et d'autres pas.

_________________
username : panoramic@jack-panoramic password : panoramic123
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://panoramic.free-boards.net
Klaus

avatar

Nombre de messages : 11088
Age : 69
Localisation : Ile de France
Date d'inscription : 29/12/2009

MessageSujet: Re: ADR_STRING(V)   Ven 9 Fév 2018 - 18:39

Si, on peut faire ça. Pour KGF.dll, je le fais tout le temps. Dans une DLL, on peut lire une chaîne Panoramic passée en paramètre, et on peut également remplacer son contenu par d'autres caractères. La seule chose impossible, c'est de changer sa longueur et d'en créer une nouvelle, à partir de la DLL.

KGF.dll est écrit en Delphi V6 Personal Eidition. Voici comment on fait, dans cette configuration (à adapter éventuellement  d'autres langues):

Panoramic:
Code:

dim a$
a$ = "Ceci est ma chaîne de caractères"
res% = dll_call1("Test",adr(a$))

Lire cette chaîne dans la fonction Test de la DLL en Delphi
Code:
function Test(chaine: pstring):integer; stdcall; export;
var
  s: string;
begin
  s := chaîne^;
  showmessage('La chaîne contient: '+s);
...
  result := Length(s);
end;

En fait, l'expression Panoramic adr(a$) fournit l'adresse d'un pointeur vers la chaîne. C'est exactement ce que représente un pstring en Delphi. Là où pstring n'est pas défini, il suffit de le déclarer comme ceci:
Code:
type
  pstring = ^string;
end;

Maintenant, pour changer les caractères du string passé en paramètre, je passe par une boucle utilisant des pointeurs de type pbyte (là encore: pbyte = ^byte;). Comme ceci, en remplaçant le texte de l'exemple ci-dessus par des "x" (ou n'importe quoi d'autre):
Code:
procedure CopyStringToPanoramic(sInput: string; aOutput: pstring);
var
  pi, po: pbyte;
begin
  pi := pbyte(@sinput[1]);
  po := pbyte(pinteger(aOutput)^);
      // ici, on prend la valeur passée par Panoramic: adr(a$)
      // on la considère comme un pointeur vers un entier (justement, vers la vraie adresse du string)
      // on déréférence ce pointeur ce qui fournit la vraie adresse du string
      // et pour finir, on considère cette adresse comme une adresse d'un octet (pbyte)
  // maintenant, on boucle jusqu'à ce qu'on bute contre la fin de la chaîne en sortie (a$).
  // Cette fain est toujours déterminée par un octet de valeur 0
  repeat
    if pi^<>0 then begin  // la chaîne en entrée n'est pas terminée ?
      po^ := pi^;   // copier un octet
      inc(pi);     // passer au prochain caractère en entrée
    end else begin   // la chaîne en entrée est terminée
      po^ := 32;    // alors remplir par des espaces
    end;
    inc(po);    // passer au prochain caractère en sortie
  until pi^=0;  // et arrêter si la sortie est complète
end;

function Test(chaine: pstring):integer; stdcall; export;
var
  s, snew: string;
begin
  s := chaîne^;
  showmessage('La chaîne contient: '+s);
...
  sNew := 'xxxxxxxxxxx';
  CopyStringToPanoramic(snew,chaine);
  result := Length(s);
end;

Bon courage !

EDIT

Mais attention à ce qut tu fais avec une chaîne de caractères reçue de Panoramic ! Tu auras par exemple des problèmes si tu veux la mettre dans une TStringList, par exemple. Ceci tient à une optimisation interne de Delphi. Tant que tu ne fais que "copier" une chaîne, en réalité, tu ne déplaces qu'un pointeur vers la chaîne, en incrémentant son compteur de référence. Lorsque le programme s'arrête, la chaîne de caractères Panoramic d'origine est supprimée. Et lorsque Delphi veut supprimer la TSTringList, par exemple, le pointeur vers la chaîne indique un endroit dans la mémoire qui a déjà été libéré. Et donc, BOUM ! Violation de mémoire.

Les manières d'éviter cela:
1. au lieu de faire
Code:
MaStringList.Add(chaîne^);
ou
Code:
var
  s: string;
begin
  s := chaine^;
  MaStringList.Add(s);
il faut utiliser un système de copie similaire à celui décrit ci-dessus pour copier la chaîne Panoramic dans une variable Delphi intermédiaire, puis affecter cette variable.
2. on affecte une chaîne modifiée pour "tromper" le compilateur de Delphi:
Code:
MaStringList.Add(Trim(chaîne^)+' ');

Simple, non ?
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://klauspanoramic.comxa.com/index.html
silverman

avatar

Nombre de messages : 659
Age : 46
Localisation : Picardie
Date d'inscription : 18/03/2015

MessageSujet: Re: ADR_STRING(V)   Sam 10 Fév 2018 - 11:31

@jack
en fait c'est pour pouvoir envoyer le bon pointeur(descripteur ?) de chaine à une dll windows. Dans cet extrait de code:
Code:
Path$=dir_current$
lpszLongPath%=ADR(Path$)
dword% = DLL_CALL3("GetShortPathNameA", lpszLongPath%, lpszShortPath%, cchBuffer%)
'lpszLongPath%' n'est pas bon. La bonne valeur serait lpszLongPath%=peek(ADR(Path$)) mais peek ne fonctionne que sur un octet.

@klaus
c'est valable pour une dll que l'on aura codé, mais pas pour une dll windows.
Revenir en haut Aller en bas
Voir le profil de l'utilisateur
Klaus

avatar

Nombre de messages : 11088
Age : 69
Localisation : Ile de France
Date d'inscription : 29/12/2009

MessageSujet: Re: ADR_STRING(V)   Sam 10 Fév 2018 - 12:26

Citation :
c'est valable pour une dll que l'on aura codé, mais pas pour une dll windows.
Pas tout à fait. Une DLL Windows s'attend à trouver un PCHAR, par un PSTRING. Or, adr(s$) fournit l'adresse d'un string, et non un pointeur sur les caractères. C'est peut-être un problème de terminologie, mais en Delphi, c'est très clair: l'adresse d'un string n'est pas la même chose qu'un PCHAR.

Il se trouve que depuis le début, l'interface DLL de Panoramic fonctionne comme ça, avec la fonction adr() donnant l'adresse du string. Changer cela signifie imposer littéralement des dizaines de milliers de modifications à faire dans les codes de tous ceux qui codent des DLLs en Delphi pour Panoramic. Je parle bien sûr de KGF.dll, mais ne suis certainement pas le seul.

Si Jack y voit un intérêt, il pourrait ajouter une fonction du type
ADR_PCHAR(s$)
pour aller dans ton sens. Mais pour ma part, je suis fermement opposé au changement de fonctionnement de la fonction ADR().
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://klauspanoramic.comxa.com/index.html
silverman

avatar

Nombre de messages : 659
Age : 46
Localisation : Picardie
Date d'inscription : 18/03/2015

MessageSujet: Re: ADR_STRING(V)   Sam 10 Fév 2018 - 12:52

klaus a écrit:
Mais pour ma part, je suis fermement opposé au changement de fonctionnement de la fonction ADR().
Ce n'est pas ce que j'ai suggéré. Il n'est pas question de modifier la fonction ADR.
Ce que je souhaite, c'est une nouvelle fonction qui s'appelerait ADR_STRING(S$)(ou ADR_PCHAR(S$) si tu préfères) et qui retournerait comme valeur : peek(ADR(S$)).
Cela permettrais de pouvoir utiliser les fonctions des dll windows qui nécessite un pointeur de chaine comme celle-ci par exemple.
Indirectement, cela rejoint ta demande d'extension de la fonction PEEK. A la limite, si PEEK32 est créé, cette demande deviendrait superflu.
Revenir en haut Aller en bas
Voir le profil de l'utilisateur
Klaus

avatar

Nombre de messages : 11088
Age : 69
Localisation : Ile de France
Date d'inscription : 29/12/2009

MessageSujet: Re: ADR_STRING(V)   Sam 10 Fév 2018 - 12:59

Là, on se rejoint tout à fait, Silverman. C'était justement une de mes motivations pour proposer l'extension de PEEK et POKE.
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://klauspanoramic.comxa.com/index.html
Contenu sponsorisé




MessageSujet: Re: ADR_STRING(V)   

Revenir en haut Aller en bas
 
ADR_STRING(V)
Revenir en haut 
Page 1 sur 1

Permission de ce forum:Vous ne pouvez pas répondre aux sujets dans ce forum
FORUM DE DISCUSSION SUR LE LANGAGE PANORAMIC :: PANORAMIC :: Vos souhaits d'amélioration de Panoramic-
Sauter vers: