Créer une dll standard avec vb6

Créer une dll standard avec vb6

Introduction

Visual basic est considéré comme le premier programme de développement rapide d'application avec son interface graphique élégante et la facilité d'utilisation globale. C e qui a permis avec relativement peu d'expérience de programmation de réaliser en quelques minutes ce qui a souvent pris jour pour les programmeurs utilisant des langages comme C et C++.
Cependant, ce concept de langage de programmation simple destiné à des programmateurs inexpérimentés a vraiment limité VB. Certes, on peut faire beaucoup de chose avec VB comme des EXE standard, des DLL ActiveX... Mais on ne peut pas créer des DLL standard. Du moins en théorie. .

Le projet

Nous allons créer une simple bibliothèque de fonctions mathématiques qui permet d'incrémenter, de décrémenter et de calculer le carré d'un chiffre.

Créer un proxy linker

Le rôle de Link.exe est de combiner des programmes compilés avec l'extension .OBJ et générer un fichier exécutable (.exe).

Voici les paramètres de la ligne de commande passé par VB à « Link.exe » pour créer une DLL ActiveX par exemple.

"C:\Program Files\Microsoft Visual Studio\VB98\maDll\Class1.OBJ" "C:\Program Files\Microsoft Visual Studio\VB98\maDll\Module1.OBJ" "C:\Program Files\Microsoft Visual Studio\VB98\maDll\Projet1.OBJ" "C:\Program Files\Microsoft Visual Studio\VB98\VBAEXE6.LIB"

/ENTRY:__vbaS

/OUT:"C:\Program Files\Microsoft Visual Studio\VB98\maDll\Projet1.dll" /BASE:0x11000000

/SUBSYSTEM:WINDOWS,4.0

/VERSION:1.0

/DLL

/INCREMENTAL:NO

/OPT:REF

/MERGE:.rdata=.text

/IGNORE:4078

Voici les paramètres à passer pour créer une DLL standard

"C:\Program Files\Microsoft Visual Studio\VB98\maDll\Class1.OBJ" "C:\Program Files\Microsoft Visual Studio\VB98\maDll\Module1.OBJ" "C:\Program Files\Microsoft Visual Studio\VB98\maDll\Projet1.OBJ" "C:\Program Files\Microsoft Visual Studio\VB98\VBAEXE6.LIB"

/ENTRY:__vbaS

/OUT:"C:\Program Files\Microsoft Visual Studio\VB98\maDll\Projet1.dll" /BASE:0x11000000

/SUBSYSTEM:WINDOWS,4.0

/VERSION:1.0

/DEF: "C:\Program Files\Microsoft Visual Studio\VB98\maDll\DefModule1.def"

/DLL

/INCREMENTAL:NO

/OPT:REF

/MERGE:.rdata=.text

/IGNORE:4078

En gras, c'est ce qu'il faut ajouter à la ligne de commande juste avant le switch /DLL. C'est le chemin d'accés du fichier de définition de module.

Les fichiers de définition de module (.def) fournissent à l'éditeur de liens des informations sur les exportations et les attributs ainsi que d'autres données concernant le programme devant être lié. Ceux qui ont fait du C/C++ connaissent ça.

Plus d'info sur les fichiers (.def) :Fichiers de définition de module (.def)

L'objectif est de faire passer à link.exe les nouveaux paramètres.

En pratique :

  • Créer un nouveau projet EXE standard,
  • Ajouter une référence à Microsoft Scripting Runtime Library,
  • Supprimer Form1 du projet,
  • Ajouter un module de Base,
  • Ajouter le code suivant au module :
'
Option Explicit

Public Sub Main()
Dim SpecialLink As Boolean, fCPL As Boolean, fResource As Boolean
Dim intPos As Integer
Dim strCmd As String
Dim strPath As String
Dim strFileContents As String
Dim strDefFile As String, strResFile As String
Dim oFS As New Scripting.FileSystemObject
Dim fld As Folder
Dim fil As File
Dim ts As TextStream, tsDef As TextStream

strCmd = Command
Set ts = oFS.CreateTextFile(App.Path & "\lnklog.txt")
ts.WriteLine "Beginning execution at " & Date & " " & Time()
ts.WriteBlankLines 1
ts.WriteLine "Command line arguments to LINK call:"
ts.WriteBlankLines 1
ts.WriteLine " " & strCmd
ts.WriteBlankLines 2

' Determine if .DEF file exists
'
' Extract path from first .obj argument
intPos = InStr(1, strCmd, ".OBJ", vbTextCompare)
strPath = Mid(strCmd, 2, intPos + 2)
intPos = InStrRev(strPath, "\")
strPath = Left(strPath, intPos - 1)

' Open folder
Set fld = oFS.GetFolder(strPath)
' Get files in folder
For Each fil In fld.Files
    If UCase(oFS.GetExtensionName(fil)) = "DEF" Then
        strDefFile = fil
        SpecialLink = True
    End If
    If UCase(oFS.GetExtensionName(fil)) = "RES" Then
        strResFile = fil
        fResource = True
    End If
    If SpecialLink And fResource Then Exit For
Next

' Change command line arguments if flag set
If SpecialLink Then
    ' Determine contents of .DEF file
    Set tsDef = oFS.OpenTextFile(strDefFile)
    strFileContents = tsDef.ReadAll
    If InStr(1, strFileContents, "CplApplet", vbTextCompare) > 0 Then
        fCPL = True
    End If
    ' Add module definition before /DLL switch
    intPos = InStr(1, strCmd, "/DLL", vbTextCompare)
    If intPos > 0 Then
        strCmd = Left(strCmd, intPos - 1) & _
" /DEF:" & Chr(34) & strDefFile & Chr(34) & " " & _
Mid(strCmd, intPos)
    End If
    ' Include .RES file if one exists
    If fResource Then
        intPos = InStr(1, strCmd, "/ENTRY", vbTextCompare)
        strCmd = Left(strCmd, intPos - 1) & Chr(34) & strResFile & _
        Chr(34) & " " & Mid(strCmd, intPos)
    End If
    ' If Control Panel applet, change "DLL" extension to "CPL"
    If fCPL Then
        strCmd = Replace(strCmd, ".dll", ".cpl", 1, , vbTextCompare)
    End If
    ' Write linker options to output file
    ts.WriteLine "Command line arguments after modification:"
    ts.WriteBlankLines 1
    ts.WriteLine " " & strCmd
    ts.WriteBlankLines 2
End If
ts.WriteLine "Calling LINK.EXE linker"
Shell "linklnk.exe " & strCmd
If Err.Number <> 0 Then
    ts.WriteLine "Error in calling linker..."
    Err.Clear
End If
ts.WriteBlankLines 1
ts.WriteLine "Returned from linker call"
ts.Close
End Sub

Dans propriété du projet :

  • mettre objet de démarrage sur Sub Main (ça se fait automatiquement en principe)
  • Créer l'exécutable (Projet1.exe).
  • Renommer Link.exe (Sur mon ordi il se trouve dans le dossier "C:\ProgramFiles\Microsoft VisualStudio\VB98") en Linklnk.exe
  • copier Projet.exe dans le dossier
  • Renommer Projet1.exe en Link.exe

Créer

  • Créer un nouveau projet DLL ActiveX nommé "MathLib". Bien qu'il est inutile dans notre projet, ne supprimer pas Class1. VB en a besoin lors de la compilation
  • Ajouter un Module de base
  • Ajouter le code suivant au module.
'
Option Explicit

Public Const DLL_PROCESS_DETACH = 0
Public Const DLL_PROCESS_ATTACH = 1
Public Const DLL_THREAD_ATTACH = 2
Public Const DLL_THREAD_DETACH = 3

Public Function DllMain(hInst As Long, fdwReason As Long, lpvReserved As Long) As Boolean
    Select Case fdwReason
        Case DLL_PROCESS_DETACH
        ' No per-process cleanup needed

        Case DLL_PROCESS_ATTACH
            DllMain = True

        Case DLL_THREAD_ATTACH
            ' No per-thread initialization needed

        Case DLL_THREAD_DETACH
        ' No per-thread cleanup needed

    End Select
End Function

Public Function Increment(var As Integer) As Integer
    If Not IsNumeric(var) Then Err.Raise 5
    Increment = var + 1
End Function

Public Function Decrement(var As Integer) As Integer
    If Not IsNumeric(var) Then Err.Raise 5
    Decrement = var - 1
End Function

Public (var As Long) As Long
    If Not IsNumeric(var) Then Err.Raise 5
    Square = var ^ 2
End Function

Nous trouvons nos 3 fonctions mathématiques et une fonction DLLMain qui constitue le point d'entrée principal de

Exporter les fonctions

  • Ouvrer l'éditeur de texte (NotePad par exemple)
  • Ecrire les lignes suivantes

NAME MathLib
LIBRARY MathMod
DESCRIPTION "Add-on Library of Mathematical Routines"
EXPORTS DllMain @1
Increment @2
Decrement @3
Square @4

Seules les fonctions déclarées dans la section exports seront visibles.

  • Enregistrer avec l'extention (.def) dans le dossier du projet.

La déclaration NAME définit le nom de déclaration LIBRARY doit précéder la liste des fonctions exportées ou apparaissent sur la même ligne que la première fonction. Le fichier (.def) doit également donner la liste la position ordinale de chaque fonction exportée précédée d'un symbole @.
Plus de détail : Fichiers de définition de module (.def)

Retourner au projet et compilez la DLL. Cela devrait invoquer la nouveau linker.

Tester la DLL

  • Créer un nouveau projet EXE standard nommé MathLibTest
  • Ajouter un module de base
  • Ajouter au module les déclarations des 3 fonctions
Option Explicit

Public Declare Function Increment Lib "C:\Program Files\Microsoft Visual Studio\VB98\mathdll\MathLib.dll" (value As Integer) As Integer

Public Declare Function Decrement Lib "C:\Program Files\Microsoft Visual Studio\VB98\mathdll\MathLib.dll" (value As Integer) As Integer

Public Declare Function Square Lib "C:\Program Files\Microsoft Visual Studio\VB98\mathdll\MathLib.dll" (value As Long) As Long

Ajouter à la form 3 bouttons (CmdIncrement, CmdDecrement et CmdSquare) et 3 zones de texte (TxtIncrement,TxtDecrement et TxtSquare)

Ajouter au module de la form le code suivant :

Option Explicit     
Private Sub cmdDecrement_Click()        
    txtDecrement.Text = Decrement(CInt(txtDecrement.Text))      
End Sub 

Private Sub cmdIncrement_Click()        
    txtIncrement.Text = Increment(CInt(txtIncrement.Text))      
End Sub 

Private Sub cmdSquare_Click()   
    txtSquare.Text = Square(CLng(txtSquare.Text))       
End Sub 

Private Sub Form_Load() 
    txtIncrement.Text = 0       
    txtDecrement.Text = 100     
    txtSquare.Text = 2  
End Sub

Exécuter F5

Attention : Ça reste du VB. Les fonctions ne sont pas aussi rapide qu'en C/C++

Plus d'infos :
Creating a Windows DLL with Visual Basic | O'Reilly Media en anglais
How To : Make a standard DLL en anglais aussi

A voir également
Ce document intitulé « Créer une dll standard avec vb6 » issu de CodeS SourceS (codes-sources.commentcamarche.net) est mis à disposition sous les termes de la licence Creative Commons. Vous pouvez copier, modifier des copies de cette page, dans les conditions fixées par la licence, tant que cette note apparaît clairement.
Rejoignez-nous