Numéro d'article: 106553 - Dernière mise à jour: jeudi 15 janvier 2004 - Version: 3.0 PROCÉDURE : pour écrire des DLL C et les appeler dans Visual Basic
Ancien nº de publication de cet article : F106553 SommaireRésumé
Cet article décrit la procédure à suivre pour utiliser des DLL avec Visual Basic. Elle couvre les points suivants :
Section A
Section B
Plus d'informationsSECTION A1.0 Qu'est-ce qu'une DLL ?Les DLL (Dynamic Link Libraries, ou " bibliothèques de liens dynamiques " en français) sont des éléments essentiels de Windows. Une DLL contient des fonctions qui sont appelées par votre programme exécutable au cours de son exécution. En d'autres termes, une DLL est une bibliothèque de fonctions avec lesquelles votre programme peut se lier dynamiquement.Un lien peut être statique ou dynamique. Les liens statiques sont immuables. Toutes les données d'adressage nécessaires à votre programme pour accéder à une fonction de la bibliothèque sont fixées lors de la création du fichier exécutable et demeurent inchangées pendant son exécution. Les liens dynamiques sont créés en fonction des besoins. Quand votre programme a besoin d'accéder à une fonction qui ne se trouve pas dans le fichier exécutable, Windows charge la bibliothèque de liens dynamiques (la DLL) et rend toutes ses fonctions accessibles à votre application. Windows résout alors l'adresse de chaque fonction et la lie dynamiquement à votre application. Toutes les commandes personnalisées utilisées dans Visual Basic sont des DLL. La seule différence tient au fait qu'elles nécessitent une gestion spéciale sous la forme de messages reçus de Visual Basic. 1.1 Pourquoi utiliser des DLL ?Voici quatre raisons pour lesquelles vous pouvez vouloir utiliser une DLL :
1.2 Anatomie d'une DLLChaque DLL doit contenir une fonction LibMain. Elle devrait également contenir une procédure de sortie WEP (Windows Exit Procedure) en plus des fonctions exportées pouvant être appelées par un programme exécutable.
1.3 Gestion de la mémoire des DLLUtilisez le modèle mémoire de grande capacité.Le langage C stocke toutes les variables définies comme statiques ou globales (définies en dehors d'une fonction) dans le tas mémoire du programme et toutes les autres variables sur la pile. Dans le modèle de petite ou moyenne capacité, tous les pointeurs sont par défaut des pointeurs 16 bits. Cela signifie que l'accès aux données se fait par décalages de 16 bits par rapport au registre du segment de données (SD) ou au registre du segment de pile (SP). Malheureusement, le compilateur n'a aucun moyen de savoir si le décalage se fait par rapport au SD ou au SP. Dans la plupart des programmes, cela ne devrait pas poser de problème puisque le SD et le SP désignent le même segment. Les DLL constituent toutefois un cas à part. Une DLL possède son propre segment de données, mais elle partage sa pile avec le programme d'appel. Cela veut dire que le SD et le SP ne désignent pas le même emplacement. La solution la plus simple pour contourner ce problème consiste à construire une DLL sur la base du modèle mémoire de grande capacité, où toutes les variables sont référencées par une valeur de 32 bits. Pourquoi allouer de la mémoire dynamiquement ?L'allocation dynamique de la mémoire est une technique parfaitement adaptée à Windows. La déclaration de tableaux de données de grande taille prend de la place, que ce soit dans la pile de votre programme, qui est limitée à 64 Ko, ou dans le segment de données de votre programme, ce qui gaspille de l'espace disque et encombre la mémoire Windows. Il est préférable de demander de l'espace mémoire à Windows lorsque vous en avez besoin, puis de le libérer lorsque vous avez terminé.Allocation de mémoireDans Windows, vous pouvez allouer dynamiquement deux types de mémoire : la mémoire locale et la mémoire globale. La mémoire locale est limitée à 64 Ko et, dans le cas d'une DLL, elle est partagée avec le programme qui a appelé la DLL. La mémoire globale est toute la mémoire dont Windows dispose après avoir été chargé.La mémoire locale est allouée et gérée à l'aide des fonctions LocalAlloc, LocalLock, LocalUnlock et LocalFree -- comme dans cet exemple : La mémoire globale est allouée et gérée à l'aide des fonctions GlobalAlloc, GlobalLock, GlobalUnlock et GlobalFree -- comme dans cet exemple : Si vous voulez partager la mémoire allouée dans la DLL avec d'autres programmes, vous devriez l'allouer en utilisant le drapeau GMEM_SHARED. Si vous souhaitez partager la mémoire par échange dynamique de données, vous devez l'allouer en utilisant le drapeau GMEM_DDESHARE. Agissez avec prudence lorsque vous stockez de données en utilisant des variables statiquesSi vous essayez de stocker des données dans une DLL en utilisant des variables globales ou statiques, ne soyez pas surpris si ces données ont été modifiées la prochaine fois que vous charger votre DLL. Les données mémorisées de cette manière seront communes à toutes les applications qui accèdent à cette DLL. Quel que soit le nombre d'applications qui utilisent une DLL, il n'y a qu'une seule instance de la DLL. Le meilleur moyen de contourner ce problème consiste à retourner les structures de la DLL et à les réintroduire en cas de besoin.Descripteurs de fichierIl est impossible de partager des descripteurs de fichier entre des applications ou des DLL. Chaque application a sa propre table de descripteurs de fichier. Pour que deux applications utilisent le même fichier à l'aide d'une DLL, elles doivent ouvrir individuellement le fichier toutes les deux.1.4 Construction d'une DLL à l'aide de Visual C++La procédure à suivre pour construire une DLL à l'aide de Visual C++ est la suivante :
1.5 Exemple de DLL CLa DLL ci-dessous contient la fonction GetDiskInfo, qui peut être appelée dans Visual Basic. Cette fonction retourne l'espace disque disponible, le nom du lecteur courant et le nom du volume.
LIBRARY diskinfo
REMARQUE : Le nom de LIBRARY dans le fichier .DEF doit être le même que le nom du fichier .DLL, sinon Visual Basic affichera le message " Erreur au chargement de la DLL ". Par exemple, créez le fichier DISKINFO.DLL en utilisant l'instruction LIBRARY DISKINFO du fichier .DEF ci-dessus.
DESCRIPTION 'GetDiskInfo peut être appelé dans Visual Basic' EXETYPE WINDOWS 3.1 CODE PRELOAD MOVEABLE DISCARDABLE DATA PRELOAD MOVEABLE SINGLE HEAPSIZE 4096 EXPORTS GetDiskInfo @1 SECTION B2.0 Appel de DLL dans Visual BasicDans Visual Basic, toutes les fonctions que vous voulez appeler, y compris les fonctions de DLL, doivent d'abord être déclarées à l'aide de l'instruction Declare. Vous pouvez déclarer vos fonctions dans la section Déclarations d'un formulaire ou d'un module. Si vous déclarez une procédure ou une fonction de DLL dans un formulaire, elle est privée pour ce formulaire. Pour la rendre publique, vous devez la déclarer dans un module. Vous trouverez ci-dessous un exemple d'instruction Declare.Une fois que vous avez déclaré la fonction, vous pouvez l'appeler et l'utiliser comme n'importe quelle autre fonction Visual Basic. 2.1 Paramètres des DLLLes DLL étant généralement écrites en langage C, elles peuvent utiliser un large éventail de paramètres qui ne sont pas directement pris en charge par Visual Basic. En conséquence, lors du transfert de paramètres, le programmeur doit trouver le type de données approprié à communiquer.Transfert des arguments par valeur ou par référencePar défaut, Visual Basic transfère tous les arguments par référence (lors du transfert par référence, Visual Basic fournit une adresse 32 bits). Cependant, de nombreuses fonctions de DLL attendent le transfert d'un argument par valeur. Cela peut être réalisé en faisant précéder la déclaration d'argument par le mot clé ByVal.Les sections ci-après expliquent les procédures à suivre pour convertir des paramètres en Visual Basic. Paramètres numériques de 8 à 16 bitsTransférez les paramètres numériques de 8 à 16 bits (int, short, unsigned int, unsigned short, BOOL et WORD) comme Integer (nombre entier).Paramètres numériques de 32 bitsTransférez les paramètres numériques de 32 bits (long, unsigned long et DWORD) en tant que LONG.Descripteurs d'objetTous les descripteurs sont des valeurs entières uniques de 16 bits associées à une fenêtre. Comme ils sont communiqués par valeur, transférez ces paramètres en tant qu'Integer.ChaînesLes chaînes comprennent les types de données LPSTR et LPBYTE (pointeur de caractères et pointeur de caractères non signés). Transférez ces paramètres sous la forme (ByVal paramname As String). Pour passer directement des chaînes Visual Basic, transférez-les sous la forme (param As String).Pour des informations supplémentaires sur le transfert de chaînes entre Visual Basic et une DLL C, consultez l'article suivant dans la Base de connaissances Microsoft : 118643
(http://support.microsoft.com/kb/118643/
)
Procédures pour transférer une chaîne ou des tableaux de caractères entre Visual Basic et une DLL C
REMARQUE : Les chaînes Visual Basic nécessitant un traitement spécial, ne les transférez pas directement si la DLL ne le requiert pas explicitement.
Pointeurs de valeurs numériquesTransférez les pointeurs de valeurs numériques en n'utilisant tout simplement pas le mot clé ByVal.StructuresSi le type défini par l'utilisateur Visual Basic correspond à la structure escomptée par la DLL, le structure peut être transférée par référence.REMARQUE : Il n'est pas possible de transférer les structures par valeur. Pointeurs de tableauxTransférez le premier élément du tableau par référence.Pointeurs de fonctionsVisual Basic ne prenant pas en charge les fonctions de rappel, les fonctions de DLL qui incluent des pointeurs désignant des fonctions ne peuvent pas être utilisées avec Visual Basic.Pointeurs nulsLorsqu'une DLL attend un pointeur nul, transférez-le sous la forme (ByVal paramname As Any). Vous pouvez utiliser 0& comme valeur de paramname lors de l'appel de la DLL.2.2 DépannageVous trouverez ci-dessous les solutions aux problèmes les plus courants.Les ressources système ne cessent de baisser après l'appel de la DLLSi votre DLL utilise des objets GDI, vous devez penser à les libérer une fois qu'ils ont été utilisés. Cette opération peut ne pas sembler évidente dans Visual Basic, mais si vous utilisez le kit de développement de logiciel Windows lorsque vous créez un objet GDI (CreateBrushIndirect par exemple), vous devez ensuite le supprimer à l'aide de l'instruction DeleteObject.Erreur pour convention d'appel de DLL incorrecteLe plus souvent, cette erreur est due à l'omission ou à l'inclusion par erreur du mot clé ByVal dans l'instruction Declare. Elle peut aussi être due à un transfert de paramètres erronés.Erreur au chargement de la DLLCette erreur survient lorsque vous appelez une procédure de bibliothèque de liens dynamiques et que le fichier spécifié dans l'instruction Declare de la procédure ne peut pas être chargé. Vous pouvez utiliser la fonction LoadLibrary de l'API Microsoft Windows pour en savoir plus sur les raisons d'un échec de chargement de DLL.Erreur de protection mémoireDes erreurs de protection mémoire surviennent lorsque votre programme écrit sur un bloc mémoire qui ne lui appartient pas. Les deux raisons les plus courantes en sont :
2.3 Exemple de programme d'appel Visual BasicL'appel d'une DLL dans un programme Visual Basic comprend deux parties distinctes : d'abord vous déclarez la fonction, ensuite vous l'utilisez dans un code d'événement.Voici un exemple d'instruction Declare. Il convient de placer l'instruction Declare dans la section Déclarations générales d'un module ou d'un formulaire. 7 Une fois la fonction déclarée, vous pouvez l'utiliser dans un code d'événement. L'exemple ci-après utilise une fonction de la DLL dans le code d'événement Command1 Click : Les informations contenues dans cet article s'appliquent au(x) produit(s) suivant(s):
L'INFORMATION CONTENUE DANS CE DOCUMENT EST FOURNIE PAR MICROSOFT SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE. L'UTILISATEUR ASSUME LE RISQUE DE L'UTILISATION DU CONTENU DE CE DOCUMENT. CE DOCUMENT NE PEUT ETRE REVENDU OU CEDE EN ECHANGE D'UN QUELCONQUE PROFIT. | Autres ressources Autres sites d'aide
CommunautésObtenir de l'aideTraductions disponibles
|






Windows Live
Facebook
Twitter
Linkedin
Digg it
Yahoo
Delicious
StumbleUpon
Yammer
Reddit
Technorati
FriendFeed
Email

Retour au début
