Probleme avec callfunction.

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Xain
Messages : 7
Inscription : lun. 24/avr./2006 14:11
Localisation : Andolsheim

Probleme avec callfunction.

Message par Xain »

Bonjour.
Bonjour à tous.

j'utilise PB4 dans un cadre professionnel :

je m'en sers pour developper une interface entre notre ERP et un peripherique de saisie Bluetooth qui fais en meme temps douchette laser (ce peripherique a un ecran LCD).
Via une DLL qui m'a été fournie, je peux :
- ouvrir et fermer le service bluetooth
- envoyer des caracteres sur le LCD de la douchette
- recevoir des infos de la douchette (exemple, le resultat d'un douchage de code barre).

j'ai un probleme avec cette derniere fonction.

Cette fonction est sensée etre bloquante et figer le programme qui l'appelle tant que les données ne sont pas recues.
or une fois la fonction appellée, le programme poursuit sont déroulement.

voici un resumé du code :

Code : Tout sélectionner

recup$=""
If OpenLibrary(1, "EpsilonBT1002.DLL")
   result=CallFunction(1,"BTStartServiceSPP","Port série Bluetooth"); en param, le nom du service pour initialiser la connexion
   Delay(5000); on attends le temps que la liaison se fasse
result=CallFunction(1,"BTLectureDatas",toto$,3,10000); variable de stockage de l'info, nb de char a recuperer, temps d'attente
else 
End
Endif
j'ai tenté une boucle repeat/until jusqu'à ce que la variable soit non vide, ainsi que l'utilisation de CallCfunction, le tout sans résultat. la valeur de result est 0 ce qui signifie que 0 caracteres ont été recuperés.

les developpeurs de cette DLL ne m'ont signalé aucun probleme en utilisant cette DLL avec MS C++

ma question est la suivante : y a t-il une autre facon d'appeler cette fonction pour résoudre ce problème (a part changer de langage de dev, evidemment) ?

merci d'avance pour votre aide.
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message par Progi1984 »

Es tu sur que ce n'est pas plutot comme ca :
"CallFunction(1,"BTLectureDatas",@toto$,3,10000)"

Je ne pense pas que tu puisses nous passer la DLL ?
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

oui progi a raison.

1/ il faut donner le pointeur de la chaine de caractères.
2/ il faut aussi dimensionner avec Space(n) par ex la chaine à la taille désirée, sans quoi il va y avoir de l'écrasement mémoire dans l'air.

tu pourra essayer comme çà aussi (utilisation des prototypes) :

Code : Tout sélectionner

;- 
;- API pour la bibliothèque 'EpsilonBT'.
;- 

#BT_DLL = 1
#BT_BUFSIZE = 32

Prototype.l BTStartServiceSPP(ServiceName.s)
Prototype.l BTLectureDatas(*StringBuffer, StringLength.l, ReadDelay.l)

If OpenLibrary(#BT_DLL, "EpsilonBT1002.DLL")
  BTLectureDatas.BTLectureDatas = GetFunction(#BT_DLL, "BTLectureDatas")
  BTStartServiceSPP.BTStartServiceSPP = GetFunction(#BT_DLL, "BTStartServiceSPP")
EndIf

;- 
;- Example d'utilisation dans un programme.
;- 

If IsLibrary(#BT_DLL)
  
  If BTStartServiceSPP("Port série Bluetooth") 
    
    Delay(5000) 
    
    lecture.s = Space(#BT_BUFSIZE)
    
    If BTLectureDatas(@lecture, #BT_BUFSIZE, 5000) 
      MessageRequester("Lecture", lecture)
    EndIf
    
  EndIf
  
EndIf
- à essayer aussi avec PrototypeC.l à la place de Prototype.l
- et avec les chaines fixes lecture.s{n} - ça peut être pratique aussi : BTLectureDatas(@lecture.s{#BT_BUFSIZE}, #BT_BUFSIZE, 5000)
Image
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message par Dr. Dri »

dans le cas d'une chaine l'arobase est superflu puisque pour transmettre la chaine on envoi son adresse

Dri
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

oui c'est vrai, enfin tout dépend comment on prototype la fonction.

mais il faut absolument allouer la chaine de la taille désirée avant de la transmettre à la fonction de la DLL.
Image
Xain
Messages : 7
Inscription : lun. 24/avr./2006 14:11
Localisation : Andolsheim

Message par Xain »

Tout d'abord, je tiens à vous remercier de vous interesser à mon problème.

je vous avoue que c'est la première fois que je tente l'utilisation d'une DLL dans purebasic (je ne maitrise pas beaucoup cette partie).

j'ai testé le code source que vous m'avez fourni :
Si l'initialisation de la douchette se fait parfaitement, la lecture des données depuis la douchette pose le meme problème, à savoir que le programme ne se fige pas à l'appel de cette fonction. Quoiqu'il en soit, je vais le réutiliser votre portion de code dans mon programme (ce sera plus propre, y a pas photo)

j'ai contacté la conceptrice de la DLL pour qu'elle envisage de revoir la partie du code de la DLL qui doit bloquer le programme appelant.

j'ai eu l'accord de la conceptrice pour la mise à dispo de la DLL (si ca peut aider) :

http://www.samap.fr/EpsilonBT1002.zip

cordialement.
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

bon j'ai testé avec la DLL.

1/
chez moi çà ne fonctionne pas parce que j'obtiens le code d'erreur -19 : Problème de licence.

2/
la fonction BTVersionDll me renvoi une chaine vide alors qu'elle est censée avoir fonctionnée (je reçois le code 0 donc ok).

3/
que donne chez toi ce source concoctée pour tester la dll ? ( il faut activer le debugger)

Code : Tout sélectionner

;-
;- API pour la bibliothèque 'EpsilonBT'.
;-

#BT_DLL = 1
#BT_BUFSIZE = 32

Prototype.l BTStartServiceSPP(ServiceName.s)
Prototype.l BTStopServiceSPP()
Prototype.l BTEcritureDatas(StringBuffer.s, nbChar.l)
Prototype.l BTLectureDatas(*StringBuffer, nbChar.l, ReadDelay.l)
Prototype.l BTVersionDll(*StringBuffer, nbChar.l)

If OpenLibrary(#BT_DLL, "EpsilonBT1002.DLL")
  BTStartServiceSPP.BTStartServiceSPP = GetFunction(#BT_DLL, "BTStartServiceSPP")
  BTStopServiceSPP.BTStopServiceSPP   = GetFunction(#BT_DLL, "BTStopServiceSPP")
  BTLectureDatas.BTLectureDatas       = GetFunction(#BT_DLL, "BTLectureDatas")
  BTEcritureDatas.BTEcritureDatas     = GetFunction(#BT_DLL, "BTEcritureDatas")
  BTVersionDll.BTVersionDll           = GetFunction(#BT_DLL, "BTVersionDll")
EndIf

Procedure.l BTErreur(code.l)
  Select code
    Case -02 : Debug "Problème de création de l’objet port série"
    Case -11 : Debug "Le port SPP ne peut pas être démarré"
    Case -12 : Debug "Le port SPP est déjà connecté"
    Case -13 : Debug "Impossible d’arrêter un port non démarré"
    Case -14 : Debug "Pas assez de mémoire disponible pour démarrer le port"
    Case -15 : Debug "Cette fonction n’est pas disponible"
    Case -16 : Debug "Erreur non définie"
    Case -17 : Debug "Pas de port sans nom"
    Case -18 : Debug "Paramètre invalide"
    Case -19 : Debug "Problème de licence"
    Default  : Debug "OK"
  EndSelect
  ProcedureReturn code
EndProcedure

;- 
;- Vérifie l'initialisation des fonctions de la DLL.
;- 

Debug LibraryID(#BT_DLL)
Debug BTVersionDll
Debug BTStartServiceSPP
Debug BTStopServiceSPP
Debug BTLectureDatas
Debug BTEcritureDatas

;- 
;- Example d'utilisation dans un programme.
;- 

If IsLibrary(#BT_DLL)
  
  version.s = Space(#BT_BUFSIZE)
  lecture.s = Space(#BT_BUFSIZE)
  
  Select BTVersionDll(@version, #BT_BUFSIZE) 
    Case -1: Debug "Variable trop petite pour contenir la version"
    Case  0: Debug "Version : " + version
  EndSelect
  
  If BTErreur(BTStartServiceSPP("Port série Bluetooth")) >= 0
    Select BTLectureDatas(@lecture, #BT_BUFSIZE, 5000)
      Case -1 : Debug "Problème lors de la lecture"
      Case -2 : Debug "Aucun périphérique connecté sur le port SPP"
      Default : Debug "Lecture : " + lecture
    EndSelect
  EndIf
  
  If BTErreur(BTStopServiceSPP()) >= 0
    Debug "Le port SPP est arrêté."
  EndIf
  
EndIf
Le résultat chez moi :
268435456
268439936
268439728
268439776
268439808
268439856
Version :
Problème de licence
Le port SPP ne peut pas être démarré
Image
Xain
Messages : 7
Inscription : lun. 24/avr./2006 14:11
Localisation : Andolsheim

Message par Xain »

Bonsoir Flype.

j'ai les resultats suivants :

268435456
268440016
268439728
268439776
268439808
268439936
Version :
OK
Aucun périphérique connecté sur le port SPP
OK
Le port SPP est arrêté.




Il est probable que le resultat ne soit pas bon car il faut compter environ 3 à 5 secondes entre l'appel de "BTStartserviceSPP" et l'initialisation effective de la douchette bluetooth (avec mon programme 3 secondes. c'est sensiblement plus long en utilisant les prototypes).


De mon coté j'ai demandé au developpeur de revoir les fonctions d'ecriture et maintenant ca roule à peu pres (je recupere les données). : Il ont crée une fonction qui declenche le debut de la capture des données (BTStartLectureDatas()) sur la douchette et une seconde qui l'arrete (BTStopLectureDatas(*buffer, int nbcharmax)). A moi de temporiser entre les 2 fonctions (Via un delay()). Ca ne me convient pas car un operateur peut saisir plus ou moins vite (c'est comme un clavier de tph portable). j'ai demandé 2 fonctions supplementaires qui permettent de retourner le nombre de caractere deja saisi ainsi que le dernier caractère saisi. avec ca ca peut peut etre fonctionner.

j'ai repris ton premier code pour l'inclure dans mon moteur. par contre je n'arrive pas à utiliser la fonction "BTEcritureData" apres l'avoir adapté avec les prototypes: ca fait planter le programme direct.

Code : Tout sélectionner

;-
;- API pour la bibliothèque 'EpsilonBT'.
;-
OpenConsole()
#BT_DLL = 1
#BT_BUFSIZE = 32

Prototype.l BTStartServiceSPP(ServiceName.s)
Prototype.l BTStopServiceSPP()
Prototype.l BTStartLectureDatas()
Prototype.l BTStopLectureDatas(*StringBuffer, StringLength.l)
Prototype.l BTStartEcritureDatas(*StringBuffer,StringLength.l)

If OpenLibrary(#BT_DLL, "c:\windows\system32\EpsilonBT1003.DLL")
  BTStartLectureDatas.BTStartLectureDatas = GetFunction(#BT_DLL, "BTStartLectureDatas")
   BTStopLectureDatas.BTStopLectureDatas = GetFunction(#BT_DLL, "BTStopLectureDatas")
  BTStartServiceSPP.BTStartServiceSPP = GetFunction(#BT_DLL, "BTStartServiceSPP")
BTStopServiceSPP.BTStopServiceSPP=GetFunction(#BT_DLL,"BTStopServiceSPP")
BTStartEcritureDatas.BTStartEcritureDatas=GetFunction(#BT_DLL,"BTStartEcritureDatas")
  EndIf

;-
;- Example d'utilisation dans un programme.
;-
  PrintN("INIT")
  ;If IsLibrary(#BT_DLL)
Delay(10000)  
BTStartServiceSPP("Port série Bluetooth")
Delay(10000)  
Print("1"); pour voir ou ca plante
ecriture.s="lolo"; je suis pas sur de ce point la !
Print("2"); pareil
BTStartEcritureDatas(@ecriture,4); CA PLANTE LA.
Print("3") ; pas d'affichage.
 teststart= BTStartLectureDatas()
 PrintN(Str(teststart))
  ;   EndIf
      Print ("OK !")
Delay(10000)
    
    lecture.s = Space(#BT_BUFSIZE)
    
    BTStopLectureDatas(@lecture, #BT_BUFSIZE)
      MessageRequester("Lecture :", lecture)
 ;   EndIf
    

  

PrintN("fin")
Input()

j'ai vraiment un souci avec l'utilisation des dlls......

j'ai mis à disposition la V4 de la dll avec un descriptifs des fonction supplementaires http://www.samap.fr/EpsilonBT1004.zip



Si je resume .
avec mon code "de base", j'arrive a initialiser et à envoyer des infos sur la douchette
avec ton code, j'initialise la douchette, j'arrive à lire des données de la douchette, mais je n'arrive pas à envoyer des infos (j'ai merdé quelque part)

ce week end, je vais relir les tutos sur ce forum.

encore merci pour le coup de main.
Répondre