'///////////////////////////////////////////////////////////////////////////
'// Démo HDAPI Visual Basic
'///////////////////////////////////////////////////////////////////////////
'// 08/11/2002
'//
'// Copyright (c) 2002, E. Ravon (Bat)
'//
'// Auteur : manu_bat_manu@yahoo.fr
'//
'// Démonstration minimale de l'utilisation d'HDAPI en Delphi
'//
'// Ce code est un exemple d'accès en Visual Basic aux données
du logiciel HelloDOC
'// Il utilise la bibliothèque HDAPI.
'//
'// Ce code a été développé pour HelloDOC
Etendu 4.56.791
'// Ainsi que pour la version d'HDAPI.DLL associée.
'//
'// Il a été testé avec HD 4.56 étendu
'// Son fonctionnement n'est pas guaranti avec des versions plus récentes
d'HD
'//
'//
'// HelloDOC est développé par Imagine Editions.
'// Windows est une marque de Microsoft Corporation
'////////////////////////////////////////////////////////////////////////////
Fichiers : HD_VB.zip (source)
Version exécutable
Fenêtre principale
- Cet exemple permet d'exporter le contenu de l'Agenda du jour,
de façon identique à l'exemple en C.
- Il ne gère pas :
- La mémorisation en Base De Registre des paramètres
du cabinet.
Sources
La partie détaillée ici est l'import des fonctions
d'HDAPI. Hormis HDAPI.DLL et la documentation (hdapi.pdf) associée,
rien d'autre n'est indispensable. Le fichier hdapi.h peut être
utilisé comme référence, mais ne sert pas directement.
Toutes les fonctions exportées par HDAPI peuvent être
incluses dans un projet Visual Basic. Ici, le fichier Form1.frm
contient l'utilisation d'HDAPI. Le fichier Module1.bas contient
toutes les définitions relatives à HDAPI.
On détaille ensuites les différents éléments
spécifiques à l'utilisation en Visual Basic.
- Type de données personnalisés
Visual Basic ne permet pas de définir des types 'simples' de
données personnalisées (typedef en C). Ici, on
a choisi de remplacer directement les types redéfinis (ex : USHORT)
par leurs équivalents en Visual Basic lorsqu'ils existent. Cette
solution peut poser un certain nombre de contraintes (de mise à
jour), mais reste la plus simple.
Les types supportés par Visual Basic sont les suivants :
-
Nom
|
Nombre d'octets
|
Plage de valeurs
|
Byte |
1
|
0 à 255 |
Boolean |
2 |
True ou False |
Integer |
2 |
-32,768 à 32,767 |
Long |
4 |
-2,147,483,648 à 2,147,483,647 |
Single |
4 |
-3.402823E38 à -1.401298E-45 (pour les
valeurs négatives) 1.401298E-45 à 3.402823E38
(pour les valeurs positives) |
Double |
8 |
-1.79769313486232E308 à -4.94065645841247E-324
(pour les valeurs négatives) 4.94065645841247E-324
à 1.79769313486232E308 (pour les valeurs positives) |
Hormis le type Byte, tous les types sont signés,
ce qui pourra poser des problèmes dans certains cas (USHORT
par ex).
- Enumarations (enum)
Elles sont sensiblement identiques à celles présentes
en C.
- Constantes
Elles sont définies par Public Const
- Fonctions
- Pour des fonctions simples ne retournant pas de valeurs [en C
:
void fonction(param); ] on utilisera une Sub
Public Declare Sub HDCloseSession Lib "HDAPI"
()
- Pour des fonctions retournant une valeur [en C :
type fonction(param); ]
on utilisera une Function
Public Declare Function HDOpenSession Lib "HDAPI"
(network As Boolean) As Boolean
- Structures
Certaines fonctions nécessitent des types de données particuliers
définis dans HDAPI.DLL. Ces types se retrouvent dans HDAPI.H,
et doivent être redéfinis, de façon équivalente
en Visual Basic.
C'est le point faible. HDAPI utilise des structures alignées
sur des octets (pour gagner de la place lors du stockage). Visual
Basic n'est pas capable de représenter de telles structures.
Visual Basic ne peut réaliser des alignements que sur des mots
de 32 bits.
En pratique :
struct ma_structure{
int z;
char data;
short val;
char c;
}
sera représenté en mémoire par :
Adresse |
Donnée |
0
|
int z |
1
|
int z |
2
|
int z |
3
|
int z |
4
|
data |
5
|
val |
6
|
val |
7
|
c |
-
En Visual Basic, l'alignement se fait forcément
sur des mots de 32 bits. Cette méthode permet de commencer
chaque élément sur une adresse multiple de 4, ce qui
améliore les performances sur un système 32 bits.
Par contre il y a des emplacements mémoire non-utilisés
(padding) qui sont donc perdus. La même structure sera représenté
comme ceci :
Adresse |
Donnée |
0
|
int z |
1
|
int z |
2
|
int z |
3
|
int z |
4
|
data |
5
|
-- |
6
|
-- |
7
|
-- |
8
|
val |
9
|
val |
10
|
-- |
11
|
-- |
12
|
c |
13
|
-- |
14
|
-- |
15
|
-- |
- Si on range directement les données fournies par HDAPI
dans une structure du Visual Basic, les données ne vont pas
correspondre. (Si on demande le contenu de data depuis
Visual Basic, on aura la donnée formée par les 32
bits data, val et c). Il n y a pas de manière
'simple' pour résoudre ce problème en Visual Basic.
On peut :
- Etendre la structure récupérée
d'HDAPI à la main (pour la faire correspondre avec celle
de Visual Basic) et l'utiliser directement. La compacter
à la main, lorsque l'on envoie la structure à
HDAPI.
Cette méthode est la plus efficace, cependant
elle est lourde à mettre en ouvre, car il faut
pour chaque structure évaluer les zones qu'il va falloir
étendre/compacter en fonction des divers éléments
de la structure. Cette méthode est très lourde
pour de grosses structures. Elle demande aussi beaucoup de travail
lorsqu'il y a une modification des données.
- Utiliser un fichier. Oui, bien que cela ne soit pas
naturel, en passant par un fichier on résoud de manière
quasiment générique le problème. Lorsque
Visual Basic écrit/lit une structure dans un fichier,
il l'écrit/lit comme si elle était alignée
sur des octets (donc sans padding).
- Pour convertir une structure HDAPI vers Visual Basic,
on utilisera :
'=============================================
Dim data(Len(data_ag)) As Byte
MoveMemory data(0), ByVal ag, Len(data_ag)
'On copie les données "brutes" dans data
Open "TMP.TMP" For Binary As #2
Put #2, 1, data
Get #2, 1, data_ag
Close #2
'=============================================
On copie d'abord l'ensemble des octets formant la structure
(sans distinction, sous forme de tableau d'octets) dans
un fichier. On copie donc directement ce qu'a retourné
HDAPI dans un fichier. On demande ensuite à Visual
Basic de relire ces données comme une structure.
La conversion va donc se faire naturellement.
- Pour convertir une structure Visual Basic vers HDAPI,
on utilisera :
'=================================================
Dim data2(Len(data_pat)) As Byte
Open "TMP.TMP" For Binary As #2
Put #2, 1, data_pat
Get #2, 1, data2
Close #2
MoveMemory ByVal pat, data2(0), Len(data_pat)
'=================================================
On copie la structure dans un fichier, Visual
Basic va donc naturellement la copier sous forme alignée
sur des octets. On relit ensuite l'ensemble des données
sous forme de tableau que l'on passe directement à
HDAPI.
- L'énorme désavantage du fichier se situe évidemment
sur la lenteur générée par cette
opération.
- Pointeurs
Il n'existe pas de pointeurs en Visual Basic. Etant donné que
beaucoup de fonctions d'HDAPI manipulent des pointeurs sur des blocs
mémoire, ou des structures, il est nécessaire de trouver
une solution.
On représente les pointeurs sous forme de Long. On utilise
ensuite l'API Win32
Declare Sub MoveMemory Lib "kernel32.dll"
Alias "RtlMoveMemory" (Destination As Any, Source As Any,
ByVal Length As Long)
qui permet de copier un bloc mémoire dans un autre
en ayant uniquement son adresse (donc un pointeur).
De même en détournant : Declare
Function GetAddrOf Lib "KERNEL32" Alias "MulDiv"
(nNumber As Any, Optional ByVal nNumerator As Long = 1, Optional ByVal
nDenominator As Long = 1) As Long de son utilisation,
on peut obtenir l'adresse d'une variable.
Chaines de caractères
Sous Visual Basic, les chaines de caractères sont
de type String, type bien plus compliqué qu'en C.
En C, un chaine est un ensemble d'octets (un tableau) terminé
par la valeur 0 (caractère de valeur ASCII 0 et non '0'). Les
chaines peuvent être en ASCII ou en UNICODE
En Visual Basic, un chaine stocke en plus de la chaine, sa longueur,
et d'autres paramètres. Les chaines sont en UNICODE.
- Pour convertir une chaine d'HDAPI vers Visual Basic, on
récupère les octets 1 à 1 dans le tableau jusqu'au
0 terminal. Cette opération est réalisée par
:
Private Function to_string(cle()
As Byte) As String
- Pour envoyer une chaine Visual Basic à HDAPI,
on utilise une chaine standard à laquelle on rajoute le caractère
0
[chr$(0)]. Visual Basic se charge de la transcription
de l'UNICODE.
|