Page 1 sur 2

[Résolu]Gestion de libGmp-3.dll

Publié : mer. 11/juil./2007 11:32
par DarkVader
Bonjour,
Développant une application VB nécessitant l'usage de la librairie GMP (GNU Multiple Precision)
je découvre PureBasic par obligation du fait de l'obligation d'utiliser un wrapper (VB n'acceptant pas les cdecl) - de plus cette solution est plus simple que réécrire GMP :?
J'ai trouvé le code source d'une dll Purebasic ayant cet usage mais son développement concernant la gestion des espaces comporte des lacunes :
la gestion n'est pas dynamique si bien que l'affectation fixe (chaine de 700 000 caractères par défaut) induit des temps de réponses très lourds.

Avant de me lancer à acquérir une licence PureBasic afin de la recompiler après modification
(sans parler de l'acquisition de la maitrise du langage lol)
quelqu'un pourrait-il me confirmer la solution ou me l'indiquer car je ne maitrise pas du tout PB ?

Dll source
Structure mpz ; multiprecision integer
mp_alloc.l
mp_size.l
mp_limb.l
EndStructure

ImportC "libgmp-3.lib"
gmp_sprintz.l(dest.s,format.s,*n.mpz) As "___gmp_sprintf"
mpz_init(*integer.mpz) As "___gmpz_init"
mpz_clear(*integer.mpz) As "___gmpz_clear"
mpz_set_str.l(*rop.mpz,str.s,base.l) As "___gmpz_set_str"
mpz_mul(*rop.mpz,*op1.mpz,*op2.mpz) As "___gmpz_mul"
EndImport
Global s.s
ProcedureDLL mult(frst$,scnd$)

; integer -------------------------------------------------------------------------

i.mpz
j.mpz
r.mpz

mpz_init(@i) ;initialize multi-precision integer
mpz_init(@j)
mpz_init(@r)

mpz_set_str(@i,frst$,10) ;i = FirstNum$ base 10
mpz_set_str(@j,scnd$,10)
mpz_set_str(@r,"",10)

s=Space(700000)
mpz_mul(@r,@i,@j)

gmp_sprintz(s,"%Zd",@r) ;sprint the value of k into string s

mpz_clear(@r) ;de-allocate memory
mpz_clear(@j)
mpz_clear(@i)

ProcedureReturn @s.s
EndProcedure



; IDE Options = PureBasic v4.00 (Windows - x86)
; ExecutableFormat = Shared Dll
; CursorPosition = 295
; FirstLine = 233
; Folding = A5
; EnableXP
; DisableDebugger
Il me semble que la solution suivante ne doit pas être loin du compte
mais encore faudrait-il pouvoir la tester.

;s=Space(700000) remplacé par
s=Space(@r.mp_size.l + 1)
Télécharger LibGMP-3.dll

Merci de votre sollicitude.

Publié : mer. 11/juil./2007 17:38
par Ollivier
C'est quoi un GNU ? (je ne suis pas interdit de passer pour un vrai c...)

Publié : mer. 11/juil./2007 17:58
par DarkVader

Publié : mer. 11/juil./2007 18:03
par comtois
s=Space(@r.mp_size.l + 1)
La syntaxe serait plutôt
s=Space(r\mp_size + 1)
Par contre tu mets un lien vers une dll, et c'est un fichier .lib qui est importé dans le code que tu donnes.

Publié : mer. 11/juil./2007 18:30
par DarkVader
Merci de ta réponse ... reste à voir :D

Pour le fichier lib, je n'avais pas fait attention car j'ai téléchargé d'une part la librairie Windows et la dll PB compilée et d'autre part le source PB.

Sinon, toutes les sources sont là

Publié : mer. 11/juil./2007 20:20
par comtois
J'ai trouvé le fichier lib sur le forum anglais

dans ce post

Et maintenant si je reprends ton code

Code : Tout sélectionner

Structure mpz ; multiprecision integer
mp_alloc.l
mp_size.l
mp_limb.l
EndStructure

ImportC "libgmp-3.lib"
gmp_sprintz.l(dest.s,format.s,*n.mpz) As "___gmp_sprintf"
mpz_init(*integer.mpz) As "___gmpz_init"
mpz_clear(*integer.mpz) As "___gmpz_clear"
mpz_set_str.l(*rop.mpz,str.s,base.l) As "___gmpz_set_str"
mpz_mul(*rop.mpz,*op1.mpz,*op2.mpz) As "___gmpz_mul"
EndImport
Global s.s
ProcedureDLL.s mult(frst$,scnd$)

; integer -------------------------------------------------------------------------

i.mpz
j.mpz
r.mpz

mpz_init(@i) ;initialize multi-precision integer
mpz_init(@j)
mpz_init(@r)

mpz_set_str(@i,frst$,10) ;i = FirstNum$ base 10
mpz_set_str(@j,scnd$,10)
mpz_set_str(@r,"",10)
Debug "Avant"
Debug r\mp_alloc
Debug r\mp_size
Debug r\mp_limb
mpz_mul(@r,@i,@j)
Debug "--------"
Debug "Après"
Debug r\mp_alloc
Debug r\mp_size
Debug r\mp_limb
Debug "--------"
s=Space(r\mp_size+1)
gmp_sprintz(s,"%Zd",@r) ;sprint the value of k into string s

mpz_clear(@r) ;de-allocate memory
mpz_clear(@j)
mpz_clear(@i)

ProcedureReturn s
EndProcedure

Debug mult("1234","30")
Dans la fenêtre debug , j'obtiens ceci :
Avant
1
0
212872
--------
Après
2
1
212872
--------
37020
Le résultat 37020 est juste, par contre le champ r\mp_size est à zéro avant de faire le calcul , ce qui peut être cohérent, et il est à 1 après la multiplication, ce qui peut être gênant :)
Bon je n'ai pas lu la doc de GMP, je découvre cette lib, donc je ne sais pas à quoi correspondent ces champs dans la structure mpz.

Publié : mer. 11/juil./2007 21:49
par comtois
bon je viens de jeter un oeil à la doc, apparemment il faut utiliser
mpz_sizeinbase(@r,10)
Avec le code qui suit , j'obtiens
Nombre de caractères = 6
Résultat = 382540

Code : Tout sélectionner

Structure mpz ; multiprecision integer
  mp_alloc.l
  mp_size.l
  mp_limb.l
EndStructure

ImportC "libgmp-3.lib"
  gmp_sprintz.l(dest.s,format.s,*n.mpz) As "___gmp_sprintf"
  mpz_init(*integer.mpz) As "___gmpz_init"
  mpz_clear(*integer.mpz) As "___gmpz_clear"
  mpz_set_str.l(*rop.mpz,str.s,base.l) As "___gmpz_set_str"
  mpz_mul(*rop.mpz,*op1.mpz,*op2.mpz) As "___gmpz_mul"
  mpz_sizeinbase.l(*op.mpz,base.l) As "___gmpz_sizeinbase"  
  mpz_get_str(str.s,base.l,*op.mpz) As "___gmpz_get_str" 
EndImport


ProcedureDLL.s mult(Premier$, Second$)

  ; Exemple avec des entiers

  Define.mpz Nombre1, Nombre2, Resultat
  Define.s Buffer
  
  ; "multi-precision integer"
  mpz_init(@Nombre1) 
  mpz_init(@Nombre2)
  mpz_init(@Resultat)
  
  ;Charge les valeurs
  mpz_set_str(@Nombre1,Premier$,10) ; Base 10
  mpz_set_str(@Nombre2,Second$,10)  ; Base 10
  mpz_set_str(@Resultat,"",10)      ; Base 10
  
  ;Multiplie Nombre1*Nombre2 et place le produit dans Resultat
  mpz_mul(@Resultat,@Nombre1,@Nombre2)
  
  ;Nombre de caractères
  Debug "Nombre de caractères = " + Str(mpz_sizeinbase(@Resultat,10)) ; Base 10
  
  ;Buffer pour l'affichage
  Buffer=Space(mpz_sizeinbase(@Resultat,10)+2)
  
  ;Récupère le résultat dans le Buffer
  mpz_get_str(Buffer, 10, @Resultat) 
  
  ;Libère la mémoire
  mpz_clear(@Resultat) 
  mpz_clear(@Nombre1)
  mpz_clear(@Nombre2)
  
  ProcedureReturn Buffer
EndProcedure

Debug "Résultat = " + mult("1234","-310")

Publié : mer. 11/juil./2007 22:39
par DarkVader
Je te remercie de ta réponse - je vais pouvoir cotiser une licence PB.
Je ne doute pas qu'il ne doit pas y avoir photo quand à la vitesse d'exécution.

Je viens de trouver cette doc que je n'ai pas encore eu le temps de fouiller :
http://www.informatik.uni-trier.de/~mue ... th/gmp.pdf

Sinon, pour info, GMP est le must pour la gestion des grands grands nombres -
de loin devant BCmath, Ntl etc.

Ce sera tout pour ce soir.
Encore merci

Publié : mer. 11/juil./2007 22:57
par comtois
Merci pour le pdf c'est plus facile pour consulter la doc, et je suis tombé sur
char * mpz get Str (char *str, int base, mpz_t op)

Convert op To a string of digits in base base. The base may vary from 2 To 36.
If str is NULL, the result string is allocated using the current allocation function (see Chapter 14 [Custom Allocation], page 78 ). The block will be strlen(str)+1 bytes, that being exactly enough For the string And null-terminator.
If str is Not NULL, it should point To a block of storage large enough For the result, that being mpz_sizeinbase (op, base) + 2. The two extra bytes are For a possible minus sign, And the null-terminator. A pointer To the result string is returned, being either the allocated block, Or the given str.
Du coup j'ai mis à jour le code ci-dessus ,et j'en reste là moi aussi :)

[EDIT]

Elle date de 2002 la doc pdf que tu indiques, sur le site de GMP
elle date de 2006.
http://gmplib.org/gmp-man-4.2.1.pdf

Publié : ven. 13/juil./2007 19:12
par DarkVader
Merci, je suis passé de plusieurs secondes à moins de 1/2 sec pour un cryptage rsa de 5000 caractères avec une clé de 1042bits,
ce qui me convient très parfaitement.
Le top sera de me passer plus tard de cette dll wrapper, mais en attendant ça fera le compte.

Encore une fois merci.

Publié : ven. 13/juil./2007 20:05
par comtois
DarkVader a écrit :Le top sera de me passer plus tard de cette dll wrapper, mais en attendant ça fera le compte.
Le top serait que tu te passes de VB pour passer définitivement à PB :)

Publié : ven. 13/juil./2007 22:50
par DarkVader
Surement et ce serait m'apporter quoi de plus ?

Publié : sam. 14/juil./2007 5:57
par comtois
Aucune idée, je plaisantais :)

Ne connaissant pas vraiment VB, je ne peux pas comparer (j'ai fait quelques bricoles avec , pas assez pour mesurer le pour et le contre).

Je pensais aussi à tous ceux qui disent être passés de VB à PB (voir sur le forum anglais).

Ils sont convaincus que le changement est bénéfique pour eux. J'imagine que ça dépend de l'usage qu'ils avaient de VB et des fonctions annexes qu'ils pouvaient utiliser ?

Disons que le fait d'avoir ta licence, la curiosité va sûrement te pousser à tester plus en profondeur PB, et peut-être que tu franchiras le pas, comme d'autres avant toi :)

Si tu ne connais pas ce site, il y a quelques exemples à tester :
http://www.purearea.net/pb/CodeArchiv/French.html

Bon week-end

Publié : sam. 14/juil./2007 11:32
par Ollivier
@darkvader

Rien que la fonction Chr?
Est-ce qu'elle existe sous VB?
(Si oui, mea culpa)

Publié : sam. 14/juil./2007 13:25
par DarkVader
comtois a écrit :Aucune idée, je plaisantais :)

Ne connaissant pas vraiment VB, je ne peux pas comparer (j'ai fait quelques bricoles avec , pas assez pour mesurer le pour et le contre).

Je pensais aussi à tous ceux qui disent être passés de VB à PB (voir sur le forum anglais).

Ils sont convaincus que le changement est bénéfique pour eux. J'imagine que ça dépend de l'usage qu'ils avaient de VB et des fonctions annexes qu'ils pouvaient utiliser ?

Disons que le fait d'avoir ta licence, la curiosité va sûrement te pousser à tester plus en profondeur PB, et peut-être que tu franchiras le pas, comme d'autres avant toi :)
La curiosité, oui ; le temps me manquant, c'est moins probable dans l'immédiat
d'autant que la syntaxe me rappelle plus le GFA de mes débuts il y a 25 ans
que le VB que je maitrise autrement mieux et pour lequel j'ai trouvé une très nette amélioration.

Si tu ne connais pas ce site, il y a quelques exemples à tester :
http://www.purearea.net/pb/CodeArchiv/French.html

Bon week-end
Merci pour le lien - il semble intéressant.
Si je dois invoquer à nouveau PB, je saurais au moins où me tourner dans un premier temps.

Ollivier a écrit :@darkvader

Rien que la fonction Chr?
Est-ce qu'elle existe sous VB?
(Si oui, mea culpa)
Soyons sérieux, chaque langage a ses avantages qui ne se résume pas à la présence ou non de quelques fonctions (*).
Si j'avais à trouver un avantage fondamental à PB que je ne connais pas suffisamment
c'est déjà la possibilité de ne pas compiler uniquement pour windows ;
mais je n'échangerais pas avec VB ne serait-ce que
* pour la quantité de code et de doc sur le net concernant ce langage
* l'ide de développement avec l'autocomplétion et l'intellisense
* la richesse des activeX (pourtant tant décriés)
* la facilité de gestion des évènements
* l'interfacage avec les applications Microsoft etc.
De plus VB permet de « pisser » du code (après que ce soit proprement ou pas dépend essentiellement du programmeur),
j'entends par là produire des applications très rapidement.
Quant à la plupart des critiques, elles le sont souvent par des personnes ne maitrisant pas le langage ;
combien connaissent la gestion des pointeurs et les fonctions non décrites (varptr, objptr, strptr),
la possibilité d'insérer de l'ASM dans le code, etc. pour ne citer que ces quelques exemples ?
La critique principale à faire au langage est celle faite habituellement à son distributeur :
ils ont décidé de passer à tout autre chose avec .net et va te faire f..... si cela ne te convient pas,
le suivi est abandonné, pooint barre, y a rien à voir -
cette seule manière de faire ne m'incite pas à franchir le pas vers C#,
langage vers lequel je serais le plus enclin à me tourner.

(*) Encore heureux qu'une fonction aussi basique que Chr existe parmi les milliers de fonctions, méthodes ou objects de VB -
elle faisait partie des instructions de base du basic que VB a implémenté dès la version 1.
c'était du second degré j'imagine ? :)