Note : Les balises de code ajoutées sur ce tutorial ne représentent pas nécessairement la réalité (code vb). Elles ne sont là que pour indenter les syntaxes afin que ces dernières vous soient plus explicites.
Une bibliothèque de types permet de d'écrire l'interface de l'objet que vous voulez créer. La description en langage ODL est compilée avec MkTypLib pour générer un fichier TLB. Ce fichier est à inclure dans les références du projet VB.
Un fichier ODL a la syntaxe suivante :
[ uuid(<GUID>), version(<version>) ] library <Nom de la bibliothèque> { importlib("stdole2.tlb"); [ uuid(<GUID>), odl ] interface <Nom de l'interface> : stdole.IUnknown { [<attributs>]<valeur de retour> <nom méthode> (<paramètres>); } }
Tout ce qui se trouve entre crochets constitue les attributs de l'entité qui suit.
Le premier <GUID>doit être un GUID unique généré avec Guidgen. La version est de la forme Major.Minor.
Le second <GUID>(celui de l'interface) doit correspondre au GUID de l'interface, si vous implémentez une interface existante ou un nouveau GUID si votre interface n'existe pas.
Idéalement le nom de l'interface commence par un I. Viennent ensuite, la liste des méthodes qui définit l'ordre dans la vtable.
<attributs> peut comprendre helpstring, vararg, propput, propputref, propget. La valeur de retour peut être soit HRESULT, soit n'importe quel type sauf un pointeur et il est préférable que ce ne soit pas une structure. Le nom de la méthode doit être unique dans l'interface (sauf pour les propput,propputref et propget).
<paramètre> a la syntaxe suivante :
[<marshaling>] <type de donnée> <nom de paramètre>
.
<marshaling>peut être soit [in] , soit [in,out], soit [out,retval] et peut inclure defaultvalue(<valeur>).
Pour fournir une aide dans l'Explorateur d'objet de VB, vous pouvez ajouter entre n'importe quel [] l'attribut helpstring("Description") sauf dans les paramètres
Bien que VB ne puisse pas définir d'alias, il sait très bien les utiliser sauf pour les Enums . Par exemple, on peut définir un alias de long (ou même unsigned long, VB ne le gère pas directement mais peut le gérer à travers un alias. Pour les opérations, ils sont traitées comme des signés). Un alias se définit dans un fichier ODL par :
Typedef [public] < type de base> <nom de l'alias>
Les constantes se définissent obligatoirement dans un module. Les constantes se déclarent comme suit :
[ dllname("n'importe quoi") ] module <nom du module> { const <type> <nom constante> = <valeur> ; }
"n'importe quoi" c'est une chaîne quelconque puisque l'attribut dllname est obligatoire pour un module.
<type>et <valeur> ne peuvent être que des types simples : unsigned char, short, long, float (Single en VB), double, LPWSTR, LPSTR, BSTR et c'est tout......
Les chaînes sont définies comme en C : on peut inclure les séquences d'échappement telles que \n (nouvelle ligne), \t (tabulation), \r (retour à la ligne), \\ (\)...
Nom en ODL |
Nom en VB |
Taille en octets |
unsigned char |
Byte |
1 |
Short |
Integer |
2 |
Long |
Long |
4 |
Float |
Single |
4 |
Double |
Double |
8 |
currency |
Currency |
8 |
DATE |
Date |
8 |
BSTR |
String |
4 + 2 * nombre de caractères + 2 |
Object |
4 |
|
boolean |
Boolean |
2 |
VARIANT |
Variant |
16 au moins |
SAFEARRAY(<type>)* |
Tableau en paramètres |
4 |
Struct |
Type/End Type |
Somme de la taille des members |
SAFEARRAY(<type>) |
Tableau de taille variable |
24 |
<type> <nom>[<taille>] |
Tableau fixe |
Sizeof(<type>) * <taille> |
Enum |
Enum |
4 |
LPSTR | Pas d'équivalent | Nombre de caractères + 1 (ANSI) |
LPWSTR |
Pas d'équivalent |
2 * Nombre de caractères + 2 (UNICODE) |
Dans le langage ODL,une structure se définit comme suit :
typedef struct { < type > <nom> ; ... } <nom structure> ;
Dans une structure,on ne peut inclure que les types suivants :
A noter que l'on ne peut pas définir un typedef struct qui porte le nom de GUID et surement d'autres.
A noter aussi que l'on peut régler l'alignement des données afin d'obtenir un alignement différent du 4 octets de VB. Sous mktyplib, cela se fait sur la ligne de commande /align <valeur>.
Un module permet aussi de déclarer des fonctions de DLLs.
La syntaxe est la suivante :
[ dllname("nom de la dll") ] module <Nom du module> { [entry(<index ou nom>)]<type> <nom de fonction>(<paramètres>) ; ... }
<index ou nom> est soit le nom de la fonction, soit son index. <nom de la dll>est le nom de la dll (avec ou sans chemin).
A noter, une restriction dans les attributs des paramètres : on ne peut pas utiliser retval . Nous sommes donc limité à [in] et [in,out].
Tout ce qui va être définit ici doit être remplacé pour être utilisé par VB :
Pour trouver une interface déjà définie, vous pouvez utiliser l'utilitaire OleView .exe et récupérer son IID (GUID).
Tous les types de bases : Byte, Integer, Long, Single, Double, Boolean, Currency, Date, Enum sont des types qui peuvent être passés directement par valeur. Pour ces types, si le paramètre est défini :
<type> est à choisir parmi un nom d'enum, unsigned char, short,long, float, double, boolean, currency, DATE.
Il n'y pas d'autres combinaisons. A noter que pour ces types, on peut définir une valeur par défaut, qui rend le paramètre optionnel, avec l'attribut defaultvalue(<valeur>).
Les types String (BSTR, LPSTR, LPWSTR), Object (IDispatch*) et autres types objets (toutes les interfaces) sont, par définition, des types pointeurs. Pour ces types, on définit :
A noter que ByRef As Object (ou As <interface>) n'est nécessaire que lorsque l'on compte modifier la référence d'objet, ou en renvoyer une. Pour un simple passage de paramètre à des fins d'utilisation, on optera toujours pour un <gras>ByVal
Les types tableaux sont eux aussi des pointeurs :
<type> est n'importe quel type, simple, structure ou tableau.
Le dernier paramètre de la liste peut être attribué avec [out,retval] s'il est du type ByRef c'est à dire pointeur (long*, boolean*,..., BSTR*, IDispatch**, <interface>**,...). Il ne peut y en avoir qu'un seul.
Pour déclarer que la liste des paramètres n'est pas connue à partir d'un certain paramètre, on utilise ParamArray suivi d'un nom de paramètre de type tableau de Variant (sous VB). En langage ODL, il faut ajouter vararg dans les attributs de la méthode(et non dans les attributs du paramètre). Il s'en suit une définition de méthode comme suit :
[vararg] <type><nom>(<liste de paramètres connus>, SAFEARRAY(VARIANT)* <nom arg>) ;
Pour déclarer une propriété en lecture-écriture , ilfaut deux fonctions : une pour lire et une pour écrire. Nous distinguerons deux cas :
Une propriété de ce type aura deux entrées dans la vtable.En langage ODL, elle auront le prototype suivant :
Une propriété de ce type aura deux entrées dans la vtable.En langage ODL, elle auront le prototype suivant :
On peut aussi avoir des propriétés en lecture-seule ou écriture-seule en supprimant une des deux fonctions.