lundi 29 janvier 2001

Chaine de caractère

CHAÎNE DE CARACTÈRE

Type de chaîne

Chaîne courte

Les chaînes courtes ont une longueur fixe, elles ne peuvent dépasser plus de 255 caractères. Étant donné que les chaînes courtes ont une valeur fixe, leurs vitesses d'exécution sont très rapides. On peut les déclarer de deux façons, mais une seule est vraiment utile.

var
   Nom:shortstring;
   Prenom:string[30];

Lorsqu'on utilise shortstring, la longueur de la variable est automatiquement de 255 caractères. A moins d'avoir absolument besoin de 255 caractères, il n'est pas vraiment intéressant d'utiliser le type shortstring. Il est intéressant d'utiliser les chaînes courtes lorsqu'on sait que la longueur de la variable sera fixe ou que l'on sait le nombre de caractère maximum qu'il peut y avoir.

Le gain de vitesse sera appréciable si l'on fait beaucoup de manipulation sur les chaînes. Le premier élément d'une chaîne courte représente la longueur de la chaîne, ce qui peut s'avérer intéressant dans certaines situations.

Chaîne longue

Les chaînes longues sont allouées dynamiquement. Leur longueur est limitée à la taille de votre mémoire disponible. Tout le traitement pour allonger et réduire la taille de la chaîne est fait en coulisse, mais on perd un peu de vitesse.

var
  Nom:string;
  Prenom:string;

Les chaînes longues n'ont pas d'élément zéro.

Chaîne à zéro terminal

Ce type de chaîne est très utilisé lorsqu'on doit utiliser les fonctions de Windows. Les fonctions de Windows utilisent des tableaux de caractères (langage c) et utilisent donc un 0 à la fin de la chaîne afin de marquer la fin de la chaîne. On doit utiliser le type PChar lorsqu'on manipule les fonctions de windows ou bien faire de la conversion.

var
  libelle : string;
begin
  libelle := 'Bonjour'; messagebox (0, PCHAR(libelle), 'Message', mb_ok);
end;

Ce code utilise un api (très simple) afin d'afficher une boîte de message

Routine de gestion de chaîne

Voici quelques fonctions et procédures disponibles, il en existe de nombreuses autres.

Routines de traitement de chaîne AZT


Fonction Description
StrAlloc Alloue une zone tampon d'une taille donnée sur le tas.
StrBufSize Renvoie la taille d'une zone tampon de caractère alloué en utilisant StrAlloc ou StrNew.
StrCat Concatène deux chaînes.
StrComp Compare deux chaînes.
StrCopy Copie une chaîne.
StrDispose Dispose une zone tampon de caractère allouée en utilisant StrAlloc ou StrNew.
StrECopy Copie une chaîne et renvoie un pointeur à la fin de la chaîne.
StrEnd Renvoie un pointeur à la fin d'une chaîne.
StrFmt Formate une ou plusieurs valeurs dans une chaîne.
StrIComp Compare deux chaînes sans tenir compte des majuscules/minuscules.
StrLCat Concatène deux chaînes avec une longueur maximum donnée de la chaîne résultante.
StrLComp Compare deux chaînes pour une longueur maximum donnée.
StrLCopy Copie une chaîne jusqu'à une longueur maximum donnée.
StrLen Renvoie la longueur d'une chaîne.
StrLFmt Formate une ou plusieurs valeurs dans une chaîne avec une longueur maximum donnée.
StrLIComp Compare deux chaînes pour une longueur maximum donnée sans tenir compte des majuscules/minuscules.
StrLower Convertit une chaîne en minuscules.
StrMove Déplace un bloc de caractères d'une chaîne sur l'autre.
StrNew Alloue une chaîne sur le tas.
StrPCopy Copie une chaîne Pascal vers une chaîne à zéro terminal.
StrPLCopy Copie une chaîne Pascal vers une chaîne AZT avec une longueur maximum donnée.
StrPos Renvoie un pointeur sur la première occurrence d'une sous-chaîne donnée dans une chaîne.
StrRScan Renvoie un pointeur sur la dernière occurrence d'un caractère donné dans une chaîne.
StrScan Renvoie un pointeur sur la première occurrence d'un caractère donné dans une chaîne.
StrUpper Convertit une chaîne en majuscules.

Routines de traitement de chaînes shortstring (chaîne Pascal)


Fonction Description
AdjustLineBreaks Transforme les ruptures de lignes dans une chaîne en séquences CR/LF.
AnsiCompareStr Comparaison, en tenant compte des majuscules/minuscules, de deux chaînes.
AnsiCompareText Comparaison, sans tenir compte des majuscules/minuscules, de deux chaînes.
AnsiLowerCase Convertit des caractères en minuscules.
AnsiUpperCase Convertit des caractères en majuscules.
CompareStr Comparaison, en tenant compte des majuscules/minuscules, de deux chaînes.
CompareText Comparaison, sans tenir compte des majuscules/minuscules, de deux chaînes.
Concat Concatène une suite de chaînes.
Copy Renvoie une sous-chaîne d'une chaîne.
Delete Efface une sous-chaîne d'une chaîne.
DisposeStr Libère une chaîne du tas.
FmtLoadStr Charge une chaîne dans la ressource table de chaînes d'un programme.
Insert Insère une sous-chaîne dans une chaîne.
IntToHex Convertit un entier en hexadécimal.
IntToStr Convertit un entier en chaîne.
IsValidIdent Renvoie True si la chaîne spécifiée est un identificateur valide.
Length Renvoie la longueur dynamique de la chaîne.
LoadStr Charge la ressource chaîne depuis le fichier exécutable de l'application.
LowerCase Met en minuscule la chaîne spécifiée.
NewStr Alloue une nouvelle chaîne dans le tas.
Pos Recherche une sous-chaîne dans une chaîne.
Str Convertit une valeur numérique en chaîne.
StrToInt Convertit une chaîne en entier.
StrToIntDef Convertit une chaîne en entier ou à une valeur par défaut.
Trim Supprime les espaces de début et de fin et les caractères de contrôle d'une chaîne donnée.
TrimLeft Supprime les espaces de début et les caractères de contrôle d'une chaîne donnée
TrimRight Supprime les espaces de fin et les caractères de contrôle d'une chaîne donnée.
UpperCase Met en majuscule la chaîne spécifiée.
Val Convertit une valeur chaîne en sa représentation numérique.

StringList

Les stringlist permettent de gérer un tableau de phrase. Chaque ligne du tableau peut être accédées grâce à son index.

De nombreuses opérations peuvent être effectuées sur les stringlist: insertion, effacement, comparaison...

La création d'une stringlist est très aisée.

lstNom : TStrings; 
// Déclaration de TStrings au lieu de TStringList 
//pour des d'utilisations de paramatètres de la vcl.
//Création d'une instance de TStringList
lstNom := TStringList.Create;
//Ajout de chaîne dans la liste
lstNom.Add('Paul Smith');
lstNom.Add('Renée');
lstNom.Add('Nicolas');
Nom:=lstNom[2];
//insertion de plage dans la variable nom
insert('plage',Nom,3);
lstNom[2]:=Nom;

Les routines de traitement peuvent être facilement effectuées sur les stringslist.

Comment chercher et remplacer des caractères?

Comment chercher et remplacer des caractères?
function SearchAndReplace
  (sSrc, sLookFor, sReplaceWith : string) : string;
var
  nPos, nLenLookFor : integer;
begin
  nPos        := Pos(sLookFor, sSrc);
  nLenLookFor := Length(sLookFor);
  while (nPos > 0) do begin
    Delete(sSrc, nPos, nLenLookFor);
    Insert(sReplaceWith, sSrc, nPos);
    nPos := Pos(sLookFor, sSrc);
  end;
  Result := sSrc;
end;

dimanche 14 janvier 2001

Comment vérifier si un fichier est utilisé?

Comment vérifier si un fichier est utilisé?
function IsFileInUse(fName : string) : boolean;
var
   HFileRes : HFILE;
begin
   Result := false;
   if not FileExists(fName) then exit;
   HFileRes :=
     CreateFile(pchar(fName),
                GENERIC_READ or GENERIC_WRITE,
                0, nil, OPEN_EXISTING,
                FILE_ATTRIBUTE_NORMAL,
                0);
   Result := (HFileRes = INVALID_HANDLE_VALUE);
   if not Result then
   CloseHandle(HFileRes);
end;

vendredi 5 janvier 2001

Learn Pascal

Delphi est basé sur pascal, alors autant le connaître. Bien connaître le pascal, facilitera le développement sous delphi. 

Les routines de bas niveau du pascal nous serons présentées afin d'optimiser au mieux notre code delphi. La qualité de ce livre est phénoménale, on lit et on comprend aussitôt tellement que les exemples sont compréhensifs. De nombreux aspects que les autres livres oublient trop souvent d'expliquer sont précisés dans cet ouvrage: pointeur, tri de donnée, recherche de données... 

Ces aspects sont très bien détaillés, ce qui m'a vraiment surprit, car ce sont des concepts complexes à apprendre. 

C'est un livre en anglais, qui est aisé à lire et qui s'adresse à celui qui veut approfondir ses connaissances afin d'améliorer son code. Après la lecture de ce livre, les côtés sombres de Delphi vous sembleront plus claire. Le livre inclut une version complète de Delphi 4 standard.

mardi 2 janvier 2001

Dll

DLL

Les dll (dynamic link library) sont très répandues dans la programmation Windows. Une dll est en fait une portion de code exécutable d'un fichier ayant une extension dll. N'importe quel programme peut faire appel à une dll.

Avantage d'une dll

  • Réutilisation du code
  • Partage du code entre plusieurs applications
  • Fractionnement du code
  • Meilleure gestion des ressources de Windows

Création d'une dll

Allez dans le menu File, cliquer sur New..., choisisez Dll



Syntaxe d'une dll


library Calculer;
uses
  SysUtils,
  Classes;
var //déclaration des variables
  TPS: double;
  TVQ: double;
  
//déclaration de la fonction
function CalculerTotal(Somme:double):double;register;
begin
  Somme := Somme * TPS + Somme;
  Somme := Somme * TVQ + Somme;
  Result := Somme;
end;

//exportation de la fonction afin de pourvoir l'utiliser dans les programmes
exports
  CalculerTotal;
  
//initialisation des variables
//peu pratique étant donné que la valeur des taxes peuvent changer
begin
  TPS:=0.07;
  TVQ:=0.065;
end.
Pour créer la dll, allez dans le menu project et cliquez sur build «nom du projet»

Portée d'une fonction ou procédure

Les fonctions et les procédures peuvent être locaux ou exportées à une dll.

Locale

Les fonctions et procédures locaux ne peuvent être utilisées qu'à l'intérieur de la dll. Il est imppossible d'y faire référence à l'extérieur de celle-ci donc aucun programme ne peut l'appeler.

Exporté

Les fonctions et procédures exportées peuvent être utilisées à l'extérieur de la dll. Les programmes peuvent appeler une telle fonction ou procédure.
Le code source ci-dessus utilisait une fonction exportée
Le mot Exports ainsi que le nom de la fonction doivent être inscrits
exports CalculerTotal;

Les deux types de fonction et procédure peuvent être utilisées simultanément dans une dll.

Chargement d'une dll

En delphi, il existe deux types de chargement pour une dll
  • Chargement statique
  • Chargement dynamique

Chargement statique

Lorsque l'application démarre la dll est automatiquement exécuté. Elle reste en mémoire tout au long de l'exécution du programme. Elle est simple d'utilisation. Il suffit d'ajouter le mot external à la procédure ou fonction afin de l'utiliser.

function CalculerTotal(Somme:double):double;register; external 'Calculer.dll';
Si la dll n'est pas trouvée, le programme ne pourra s'exécuter.

Code source disponible ici

Chargement dynamique

La dll est chargé en mémoire selon vos besoins. Sa mise en oeuvre est beaucoup plus complexe car vous devez charger et décharger la dll de la mémoire. La mémoire est utilisée plus adéquatement et l'application fonctionne plus rapidement. Il y a quelques règles que le programmeur doit suivre afin que tout fonctionne correctement.
  • Déclarer un type qui décrit la fonction ou la procédure
  • Charger la fonction ou procédure
  • Récupérer l'adresse de la fonction ou procédure
  • Appeler la fonction ou procédure
  • Décharger la fonction ou procédure

Déclarer un type qui décrit la fonction

TypeTCalculerTotal = function(Somme:double):double;

Charger la fonction ou procédure

dllInstance := loadlibrary('Calculer.dll');

Récurpérer l'adresse de la fonction

@CalculerTotal :=getprocaddress(dllInstance,'Calculerotal');

Appeler la fonction

Somme:=CalculerTotal(Somme);

Décharger la fonction

freelibrary(dllInstance);

L'allocation dynamique exige plus de travail, mais les ressources mémoires sont mieux gérées. 
Si on doit faire usage de la dll tout au long du programme, l'allocation statique est préférable. 

N'oubliez pas d'utiliser les block try except et try finally pour éviter les erreurs
Code source disponible ici

Méthode d'appel de fonction et procédure
Il existe quelques conventions pour appeler une fonction ou procédure. Comme vous avez pu remarquer dans la section chargement statique, j'ai utilisé le mot register pour appeler la fonction.

Sommaire des conventions d'appels


Directive Ordre de paramètre Utilité
register Gauche - Droite La plus efficace, évite des accès sur la pile
pascal Gauche - Droite Comptabilité antérieure
cdecl Droite - Gauche Utilisé pour les appels de dll écrite en c, c++
stdcall Droite - Gauche Appel pour les api Windows
safecall Droite - Gauche Appel pour les api Windows

Exportation de chaîne de caractère

Les dll créer à l'aide de Delphi peuvent être utilisé dans d'autre langage. Pour cette raison, on ne peut utiliser n'importe qu'elle type de donnée. Les types qui existe en Delphi n'existe pas nécessaire sous d'autre langage. Il est préférable d'utiliser des types de données natif de Linux ou Window. La dll pourra ainsi être utilisé par d'autre programmeur qui utilise d'autre langage que celui que nous utilisons.

Il est possible d'utiliser les strings et les dynamic array de Delphi dans une dll. Il faut inclure l'unité ShareMem dans la dll et le programme qui l'utilise. De plus cette unité devra être la première dans chaque fichier du projet. Il faut être certain que la dll sera utilisé que dans delphi sinon des problèmes surviendront.

Les strings telle que nous les connaissons n'existe pas en C, C++... nous utiliserons alors les PChar.

PChar

Les PChar ont leur premier caractère à l'indice zéro contrairement au string qui commmence à 1. Un PChar est une chaîne de tableau de caractère qui se termine par Nul (#0). Qui a dit C? Aussitôt que le caractère nul est trouvé c'est la fin de la chaîne.
Nous allons créer un exemple afin de montrer l'utilisation de string dans une dll. Le programme envoirera une string à la dll. Cette dll mélangera les caractères et retournera la string au programme.

Voici le code de la dll
library mixstr;

uses
  SysUtils,
  Classes;

{$R *.res}

Function MixToStr(StrText:PChar):Pchar;stdcall;
var
  i, j : Integer;
  c1   : Char;
Begin
  For i:=Length(StrText)-1 downto 0 Do
  Begin
    j:=Random(i)+1;
    c1:=StrText[i];
    StrText[i]:=StrText[j];
    StrText[j]:=c1;
  End;
  result := StrText;
End;

exports
  MixToStr;

begin
end.
Voici le code du programme
var
  Form1: TForm1;
  function MixToStr(str:PChar):PChar;stdcall; external 'mixstr.dll';

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
   edtRecu.Text := MixToStr(pchar(edtEnvoyer.Text));
end;
 

Code source disponible ici