Utilisation de DLLs en PANORAMIC

Dernière mise à jour : 9 Novembre 2010


  1. Règles d'utilisation des DLLs
  2. Exemple : un générateur de nombres aléatoires
    1. Introduction
    2. La DLL en FreeBASIC
    3. Le programme en PANORAMIC
    4. Résultats
  3. Conclusion
  4. Remerciements

I. Règles d'utilisation des DLLs

(Note : Les informations suivantes proviennent du forum PANORAMIC)

  1. La DLL est chargée en mémoire par l'instruction dll_on "xxx.dll", où xxx.dll est le nom de la bibliothèque.

    Quand la DLL n'est plus nécessaire, la mémoire peut être libérée par l'instruction dll_off

  2. La syntaxe d'appel d'une fonction de DLL est de la forme :

      result% = dll_calln("DllFunctionName", par1%, ..., parn%)
    

    n est un entier de 0 à 6 qui représente le nombre de paramètres passés à la fonction. Il y a en fait 7 routines différentes :

      dll_call0("DllFunctionName")
      dll_call1("DllFunctionName", par1%)
      dll_call2("DllFunctionName", par1%, par%2)
      ..........................................
    

    Le premier paramètre est une chaîne contenant le nom de la fonction appelée. Il est suivi par les paramètres de la fonction, qui sont obligatoirement de type entier.

    Notez aussi que :

  3. Par défaut, tous les paramètres sont passés par valeur. Si la fonction requiert un paramètre passé par référence, il faut utiliser la fonction adr() de PANORAMIC. Cette fonction s'applique aux variables simples de type entier, réel ou chaîne de caractères. Dans ce dernier cas cependant, le paramètre de la fonction appelée doit être un pointeur sur une chaîne à zéro terminal.

  4. Au stade actuel du développement de PANORAMIC, aucun tableau ne peut être passé, ni par valeur ni par référence avec adr().

  5. L'appel des fonctions doit se faire selon la convention stdcall.

  6. Le nom de la fonction appelée ("DllFunctionName") doit respecter les majuscules et les minuscules.

Si l'on prend l'exemple d'une DLL nommée fbdll.dll et écrite en FreeBASIC, la syntaxe pourrait être la suivante :


  extern "Windows-MS"

  function IntFunc(n as integer) as integer export
  ' fonction à paramètre entier
    ..............

  function RealFunc(byref x as double) as integer export
  ' fonction à paramètre réel (double précision)
    ..............
    
  function StrFunc(byref p as zstring ptr) as integer export
  ' fonction à paramètre chaîne de caractère
    ..............

  end extern

L'appel de ces fonctions par PANORAMIC se ferait de la manière suivante :


  dim n%, x, s$, result%

  dll_on "fbdll.dll"

  result% = dll_call1("IntFunc", n%)
  result% = dll_call1("RealFunc", adr(x))
  result% = dll_call1("StrFunc", adr(s$))

  dll_off


II. Exemple : un générateur de nombres aléatoires

II.A. Introduction

Le but de cet exemple est d'implémenter en PANORAMIC le générateur de nombres aléatoires Mersenne Twister qui est considéré comme l'un des plus fiables. Comme c'est le générateur par défaut en FreeBASIC, nous écrirons la DLL dans ce langage.

II.B. La DLL en FreeBASIC

Voici le code source de notre DLL (fichier ranmt.bas):


  ' *******************************************************************
  ' Generateur de nombres aleatoires "Mersenne Twister"
  ' *******************************************************************

  extern "Windows-MS"

  function InitMT(Seed as integer) as integer export
  ' Initialise le generateur
    randomize Seed
    InitMT = 0
  end function

  function RanMT(byref X as double) as integer export
  ' Retourne un reel aleatoire dans [0, 1)
    X = rnd
    RanMT = 0
  end function

  function IRanMT as integer export
  ' Retourne un entier aleatoire dans [-2^31, 2^31 - 1]
    IRanMT = int((rnd - 0.5) * 4294967296.0)
  end function

  function IRanMT1(N as integer) as integer export
  ' Retourne un entier aleatoire dans [0, N]
    IRanMT1 = int(rnd * (N + 1))
  end function

  function IRanMT2(A as integer, B as integer) as integer export
  ' Retourne un entier aleatoire dans [A, B]
    IRanMT2 = A + int(rnd * (B - A + 1))
  end function

  end extern

La compilation se fait par :

  fbc ranmt.bas -dll

On obtient deux fichiers : ranmt.dll et libranmt.dll.a. Seul le premier est nécessaire pour notre application.

II.C. Le programme en PANORAMIC

Le programme suivant utilise la DLL précédente pour simuler un jeu de dés :

  ' ---------------------------------------------------------
  ' Simulation d'un jeu de des avec test de khi-2
  '
  ' La DLL RANMT procure le generateur de nombres aleatoires
  ' "Mersenne Twister"
  ' ---------------------------------------------------------

  dim f%, nt%, i%, d%, n%(6), khi2, diff

  f% = 100      : ' Frequence attendue pour chaque face
  nt% = 6 * f%  : ' Nombre total de lancers

  dll_on "ranmt.dll"

  ' Initialise le generateur (essayer differentes valeurs)

  i% = dll_call1("InitMT", 123456789)

  ' Faire nt% lancers
  ' Chaque face devrait sortir environ f% fois

  for i% = 1 to nt%
    d% = dll_call2("IRanMT2", 1, 6)
    n%(d%) = n%(d%) + 1
  next i%

  dll_off

  ' Calculer khi-2

  khi2 = 0
  for i% = 1 to 6
    diff = n%(i%) - f%
    khi2 = khi2 + diff * diff / f%
  next i%

  ' Afficher les resultats

  print "Simulation d'un jeu de des"
  print "--------------------------"
  print
  for i% = 1 to 6
    print "Frequence du "; i%; " = "; n%(i%)
  next i%
  print
  print "khi2 = "; khi2

  end

La comparaison entre la fréquence observée pour chaque face et la fréquence théorique est réalisée par un test de χ² (khi-2) :

χ² = Σi=1..p (Oi - Ci)² / Ci

p désigne le nombre de classes, Oi et Ci respectivement les fréquences observées et calculées. Dans notre cas, p = 6, Oi = n%(i%) et Ci = f%.

Cette somme a p - 1 = 5 degrés de liberté. Dans ces conditions, la valeur critique du χ² ayant une probabilité de 95% d'être dépassée est 11,07

II.D. Résultats

L'exécution de ce programme donne les résultats suivants :

  Simulation d'un jeu de des
  --------------------------
  
  Frequence du 1 = 98
  Frequence du 2 = 122
  Frequence du 3 = 97
  Frequence du 4 = 96
  Frequence du 5 = 81
  Frequence du 6 = 106
  
  khi2 = 9.1

Les fréquences observées diffèrent des fréquences théoriques ; toutefois le χ² reste inférieur à la valeur critique : ces différences ne sont donc pas statistiquement significatives.

Il est conseillé de tester le programme avec différentes initialisations et des valeurs croissantes de f%.


III. Conclusion

Malgré quelques limitations dans la syntaxe d'appel des fonctions, les DLLs constituent un moyen simple pour étendre les fonctionnalités de PANORAMIC.

Le prochain article montrera comment utiliser une DLL pour programmer une calculatrice.


IV. Remerciements

J'exprime à nouveau ma gratitude aux membres du forum PANORAMIC, en particulier :




Retour au sommaire