1. Commencez votre premier projet DLL
1.File-> Fermer tout-> Fichier-> Nouveau [DLL >
Code : |
// générer automatiquement du code comme suit Bibliothèque Project2; // c'est un non-sens. usages Sysutils, Classes {$ R * .res} Commencer fin. |
2. Ajoutez une func pour entrer:
Code : |
Bibliothèque Project2; usages Sysutils, Classes Fonction mymax (x, y: entier): entier; Commencer Si x> y alors Résultats: = x autre Résultats: = y; fin ; // N'oubliez pas: le nom de la bibliothèque n'a pas d'importance, mais le cas de DLL-FUNC est lié. // L'écriture de mymax en dll-func-name est différente de Mymax. Si c'est mal écrit, immédiatement // Le résultat est que vous demandez que l'AP qui utilise cette DLL ne peut pas être ouverte du tout. // Le boîtier supérieur et inférieur des paramètres est OK. Il n'a même pas besoin d'avoir le même nom. Si le prototype est (x, y: entier) // Écrivez-le comme (a, b: entier) dans le temps, c'est OK. // N'oubliez pas: ajoutez un autre stdcall. Le livre dit que si vous écrivez des DLL à l'aide de Delphi et espérez non seulement // Si Delphi-AP espère également utiliser BCB / VC-AP, etc., alors vous feriez mieux d'ajouter un stdcall; // Modèle de paramètre: Delphi a de nombreux modèles variables, qui ne sont bien sûr pas ce que Dll aime //, la langue maternelle de Windows / DLL devrait être C. Donc, si nous voulons transmettre et sortir les paramètres de la DLL, nous // utilise autant que possible selon les règles. Si vous écrivez ces deux-là, ce dernier aura beaucoup de mal. Si vous n'êtes pas familier avec C // Si c'est bien. Nous en parlerons plus tard. {$ R * .res} Commencer fin. |
3. Envoyez ces funcs partageables de la DLL et laissez le monde extérieur (c'est votre Delphi-AP): Guangru
Par conséquent, votre AP ne peut pas les utiliser, vous devez ajouter des exportations.
Code : |
{$ R * .res} exportations Mymax; Commencer fin. |
4. D'accord, vous pouvez appuyer sur Ctrl-F9 pour compiler. N'appuyez pas sur F9 pour le moment. DLL n'est pas exe┌ qui ne peut pas être exécuté séparément. Si la DLL a une erreur pour le moment, veuillez la corriger. Appuyez à nouveau sur Ctrl-F9. L'avertissement peut être là pour le moment, cela n'a pas d'importance, il suffit de l'étudier et de jeter un œil. Appuyez à nouveau sur Ctrl-F9, puis "fait, compilé". Il y aura un * .dll dans le même répertoire. Félicitations, la tâche est accomplie.
2. Effectuer un test: ouvrez une nouvelle application:
1. Ajouter un tbutton
Code : |
ShowMessage (intToStr (mymax (30,50))); |
2. Dites à Exe d'y aller pour attraper une func
Code : |
// ajouter à la forme, interface, var Fonction myMax (x, y: entier): entier; // mytestdll.dll écrit le nom du projet DLL avant vous avant // Peu importe si le nom de la DLL est supérieur et inférieur. Mais n'oubliez pas d'ajouter une extension .dll. Sur win95 ou nt, // Il n'est pas nécessaire d'ajouter une extension, mais ces deux OSS peuvent être de moins en moins. Vous devez ajouter une extension. |
Ok, c'est simple.
L'exemple ci-dessus est-il très simple? Les amis qui connaissent Delphi peuvent voir que le code ci-dessus est essentiellement le même que la rédaction d'un programme général Delphi, sauf qu'il existe un paramètre STDCALL supplémentaire après la fonction TestDLL et la fonction TestDLL est déclarée à l'aide de l'instruction Exportts. Compilez simplement le code ci-dessus et vous pouvez obtenir une bibliothèque de liens dynamiques appelée Delphi.dll. Maintenant, voyons ce qui a besoin d'attention. 1. Toutes les fonctions ou procédures écrites en DLL doivent être ajoutées avec les paramètres d'appel STDCALL. Dans l'environnement Delphi 1 ou Delphi 2, le paramètre d'appel est loin. Après Delphi 3, ce paramètre a été modifié en stdcall, dans le but d'utiliser la technologie de transfert de paramètres Win32 standard au lieu des paramètres de registre optimisés. Oublié d'utiliser le paramètre stdcall est une erreur courante. La raison en est que le paramètre de registre est le paramètre par défaut de Delphi.
2. Les fonctions et procédures écrites doivent être déclarées comme des fonctions externes à l'aide de l'instruction Exportations.
Comme vous pouvez le voir, la fonction TestDLL est déclarée comme une fonction externe. Cela permet de voir la fonction à l'extérieur. (S'il n'y a pas d'option de vue rapide, vous pouvez l'installer à partir d'un CD Windows.) La fonction TestDLL apparaît dans la barre de table d'exportation. Une autre bonne raison est que si nous ne déclarons pas de cette façon, les fonctions que nous écrivons ne seront pas appelées, ce que personne ne veut voir.
3. Lorsque des paramètres de type de chaîne longs et des variables sont utilisés, le partagemm doit être référencé.
Le type de chaîne dans Delphi est très puissant. (Oui, vous le lisez correctement, il s'agit en effet de deux mégaoctets.) Pour le moment, si vous insistez pour utiliser un paramètre de type de chaîne, une variable ou même des informations d'enregistrement, vous devez vous référer à l'unité ShareMem, et ce doit être la première référence . Il s'agit de la première unité référencée après l'instruction USE. Comme indiqué dans l'exemple suivant:
usages
Partagem,
Sysutils,
Classes
Un autre point est que la même chose doit être effectuée dans votre fichier de projet (* .dpr) au lieu du fichier unitaire (* .pas). Si vous ne faites pas cela, vous êtes susceptible de payer un accident. La façon d'éviter d'utiliser le type de chaîne est de déclarer des paramètres, des variables, etc. du type de chaîne en tant que type phar ou shortstring (tel que: s: chaîne [10]). Le même problème se produit lorsque vous utilisez des tableaux dynamiques, la solution est comme décrit ci-dessus.
Chapitre 3: Appel statique à DLL en haut à Delphi
Appeler une DLL est plus facile que d'écrire une DLL. Tout d'abord, je vous présenterai la méthode d'appel statique. De même, donnons d'abord un exemple d'appels statiques.
unité unité 1;
interface
usages
Windows, messages, systèmes, classes, graphiques,
Commandes, formulaires, boîtes de dialogue, stdctrls;
taper
Tform1 = classe (tform)
Edit1: Tedit;
Button1: Tbutton;
Procédure Button1Click (expéditeur: tobject);
Privé
{Déclarations privées}
publique
{Déclarations publiques}
fin;
var
FORM1: TFORM1;
Mise en œuvre
{$ R * .dfm}
// Le code suivant dans cette ligne est le code que nous avons vraiment écrit
fonction testdll (i: entier): entier; stdcall;
«Delphi.dll» externe;
Procédure tform1.button1Click (expéditeur: tobject);
Commencer
Edit1.text: = intToStr (testDll (1));
fin;
fin.
Dans l'exemple ci-dessus, nous avons placé une boîte d'édition (édition) et un bouton sur le formulaire, et avons écrit très peu de code pour tester le Delphi.dll que nous venons d'écrire. Vous pouvez voir que le seul travail que nous faisons est de mettre la partie description de la fonction TestDLL dans l'implémentation et de spécifier l'emplacement de Delphi.dll avec l'instruction externe. (Dans cet exemple, le programme d'appels et Delphi.dll sont dans le même répertoire.) Il est passionnant que la fonction TestDLL que nous nous sommes écrites soit rapidement reconnue par Delphi. Vous pouvez faire une expérience comme celle-ci: entrez "TestDll (", et bientôt Delphi utilisera la barre d'invite à mouche pour vous inviter aux paramètres que vous devez saisir, tout aussi simple que l'utilisation d'autres fonctions définies dans Delphi. Les notes incluent
Suivant:
1. Utilisez Stdcall pour appeler les paramètres.
Comme mentionné ci-dessus, lorsque vous faites référence aux fonctions et procédures en DLL, vous devez également utiliser le paramètre STDCALL, pour la même raison que celle mentionnée ci-dessus.
2. Utilisez l'instruction externe pour spécifier le chemin et le nom du fichier DLL appelé.
Comme vous pouvez le voir, nous spécifions le nom du fichier DLL à appeler dans l'instruction externe. Il n'y a pas de chemin d'écriture car le fichier DLL et le programme principal qui l'appellent se trouvent dans le même répertoire. Si le fichier DLL est en c: /, nous pouvons écrire l'instruction de référence ci-dessus comme «C: /delphi.dll» externe. Notez que le suffixe du fichier.dll doit être écrit.
3. Les variables globales ne peuvent pas être appelées à partir de la DLL.
Si nous déclarons une sorte de variable globale dans la DLL, comme: var s: octet. De cette façon, la variable globale peut être utilisée normalement dans la DLL, mais S ne peut pas être utilisée par le programme d'appel, et S ne peut pas être transmis en tant que variable globale au programme d'appel. Cependant, les variables déclarées dans le programme d'appel peuvent être transmises sous forme de paramètres à la DLL.
4. La DLL appelée doit exister.
Ceci est important. Si le chemin d'accès et le nom de fichier spécifié n'existent pas ou si le chemin d'accès et le nom de fichier spécifié sont incorrects, le système invitera "une erreur s'est produite lors du démarrage du programme" ou "Fichier * .dll non trouvé" lors de l'exécution du programme principal.
Chapitre 4 Appel dynamiquement en haut DLL à Delphi
Appeler dynamiquement DLLS est relativement compliqué, mais très flexible. Pour illustrer soigneusement le problème, cette fois, nous donnons un exemple d'appel d'une DLL écrite en C ++. Tout d'abord, compilez le programme de source DLL suivant en C ++.
#inclure
extern "c" _declspec (dllexport)
int winapi testc (int i)
{
retour i;
}
Après la compilation, un fichier DLL est généré. Par souci de commodité, nous nous référons toujours au programme d'appel ci-dessus, mais remplaçons l'instruction d'origine dans le processus Button1Click par le code suivant.
Procédure tform1.button1Click (expéditeur: tobject);
taper
Tintfunc = fonction (i: entier): entier; stdcall;
var
Th: Thandle;
TF: Tintfunc;
TP: TfarProc;
Commencer
Th: = loadLibrary ('cpp.dll');
Si th> 0 alors
essayer
Tp: = getProcAddress (th, pChar ('testc'));
Si tp <> nil
Puis commence
Tf: = tintfunc (tp);
Edit1.text: = intToStr (tf (1));
fin
autre
ShowMessage («Fonction TestC non trouvée»);
Enfin
FreeLibrary (th); {libérer la dll}
fin
autre
ShowMessage («Cpp.dll non trouvé»);
fin;
Comme vous l'avez vu, cette technique d'appel dynamique est très compliquée, mais tant que vous modifiez les paramètres, tels que la modification du nom DLL dans LoadLibrary ('Cpp.Dll') pour être 'Delphi.dll', vous pouvez modifier dynamiquement le appelé dll.
1. Définissez le type de fonction ou de procédure à appeler.
Dans le code ci-dessus, nous définissons un type tintfunc, qui correspond à la fonction TestC que nous allons appeler. Le même travail de définition doit être effectué dans d'autres appels. Et ajoutez également les paramètres d'appel stdcall.
2. Libérez la dll appelée.
Nous avons appelé une DLL dynamiquement avec LoadLibrary, mais n'oubliez pas que vous devez libérer manuellement la DLL avec Freelibrary après utilisation, sinon la DLL prendra la mémoire jusqu'à ce que vous quittez des fenêtres ou que vous vous arrêtiez.
Évaluons maintenant les avantages et les inconvénients des deux méthodes d'appel DLL. La méthode statique est simple à implémenter, facile à maîtriser, et généralement légèrement plus rapide, et est plus sûre et plus fiable; Pour fonctionner jusqu'à ce que la DLL soit publiée uniquement à la fin du programme, et seuls les systèmes basés sur le compilateur tels que Delphi peuvent utiliser cette méthode. Les méthodes dynamiques résolvent mieux les lacunes dans les méthodes statiques et peuvent facilement accéder aux fonctions et procédures dans les DLL, et même des fonctions ou des procédures nouvellement ajoutées dans certaines anciennes versions de DLL; La fonction ou la procédure doit définir de nombreux types complexes et méthodes d'appel. Pour les débutants, l'auteur vous recommande d'utiliser des méthodes statiques, puis d'utiliser des méthodes d'appel dynamique après votre maîtrise.
Chapitre 5 Conseils pratiques pour utiliser DLL Top
1. Compétences d'écriture.
1. Afin d'assurer l'exactitude de la DLL, vous pouvez d'abord l'écrire dans le cadre d'une application ordinaire, la déboguer correctement, puis la séparer du programme principal et le compiler en DLL.
2. Afin d'assurer l'universalité de la DLL, vous devez empêcher les noms des contrôles visuels d'apparaître dans la DLL que vous avez écrit vous-même, tel que: Edit1 Nom dans Edit1.Text; un enregistrement.
3. Pour faciliter le débogage, chaque fonction et processus doivent être aussi courtes et concises que possible, et doivent être accompagnées d'annotations spécifiques et détaillées.
4. Try-finally doit être utilisé pour gérer les erreurs et exceptions possibles.
5. Référencer le plus d'unités que possible pour réduire la taille de la DLL, en particulier, ne référez pas à des unités visuelles, telles que les unités de dialogue. Par exemple, en général, nous ne pouvons pas référencer les unités de classes, ce qui peut réduire la DLL compilée d'environ 16 Ko.
2. Appeler les compétences.
1. Lorsque vous utilisez des méthodes statiques, vous pouvez renommer la fonction ou la procédure appelée. Dans l'exemple DLL écrit en C ++ mentionné ci-dessus, si l'instruction "C" externe est supprimée, C ++ compilera des noms de fonction étranges, et la fonction TestC originale sera nommée @ testc $ s et d'autres noms bizarres ridicules. Utilise la technologie de mangling du nom C ++. Ce nom de fonction est illégal à Delphi, nous pouvons résoudre ce problème comme ceci:
Réécrire la fonction de référence comme
fonction testc (i: entier): entier; stdcall;
«cpp.dll '; name' externe" @ testc $ s ';
La fonction du nom est de renommer.
2. Vous pouvez mettre les DLL que nous avons écrites dans le répertoire Windows ou dans le répertoire Windows / System. Cela ne peut écrire que le nom de la DLL sans écrire le chemin dans l'instruction externe ou dans l'instruction LoadLibrary. Mais il est un peu inapproprié de le faire. Mettez les DLL que vous vous êtes écrites dans le répertoire du système!
3. Compétences de débogage.
1. Nous savons que la DLL ne peut pas être exécutée et déboguée étape par étape lors de l'écriture. Il existe un moyen de le faire, c'est-à-dire configurer un programme hôte dans le menu RUN | Paramètres. Ajoutez le nom du programme hôte à la barre d'application hôte de la page locale pour effectuer un débogage étape par étape, l'observation et l'exécution des points d'arrêt.
2. Ajoutez des informations sur la version DLL. Les remarques d'ouverture ont mentionné que les informations de version sont très importantes pour les DLL. Cela vaut la peine d'ajouter un tel espace. Malheureusement, il n'est pas possible d'utiliser directement l'option de version dans le menu du projet | Comme indiqué dans l'exemple suivant:
bibliothèque Delphi;
usages
Sysutils,
Classes
{$ R * .res}
// Notez que la ligne de code ci-dessus doit être ajoutée dans cette position
fonction testdll (i: entier): entier; stdcall;
Commencer
Résultats: = i;
fin;
exportations
Testdll;
Commencer
fin.
3. Afin d'éviter de dupliquer les noms avec d'autres DLL, il est préférable d'utiliser un mélange de caractères, de nombres et de soulignements lors de la dénomination des DLL que vous écrivez. Par exemple: jl_try16.dll.
4. Si vous avez déjà compilé des DLL dans Delphi 1 ou Delphi 2, la DLL que vous avez compilée est 16 bits. Il suffit de recompiler le code source dans le nouvel environnement Delphi 3 ou Delphi 4 et vous pouvez obtenir une DLL 32 bits.
[Après la note]: En plus des méthodes les plus couramment utilisées d'utilisation des DLL introduites ci-dessus, les DLL peuvent également être utilisées comme porteurs de ressources. Par exemple, le changement d'icônes dans Windows est la ressource de la DLL utilisée. De plus, la technologie de conception DLL maîtrisée présente de nombreux avantages pour utiliser la programmation OLE, COM et ActiveX plus avancée.