Le forum (ô combien francophone) des utilisateurs de Powerbuilder.
Issu du mail slot de SEKI, entièrement commenté et légèrement amendé...
Cette classe va désormais rejoindre mon cher Framework
Bien que cette classe fonctionne très bien en la transformant en une dll C# (bravo PB !) afin qu'elle puise être utilisée dans cet environnement, sa traduction C# m'ayant été demandée elle se trouve là : mail slot C#
forward global type nvo_mailslot from nonvisualobject end type end forward global type nvo_mailslot from nonvisualobject event _commentaire ( ) end type global nvo_mailslot nvo_mailslot type prototypes Function ulong ofx_getLastError() library "kernel32.dll" alias for "GetLastError" Function boolean ofx_closeHandle (ulong hObject) library "kernel32.dll" alias for "CloseHandle" Function boolean ofx_setMailSlotInfo (ulong hMailslot, ulong lReadTimeout) library "kernel32.dll" alias for "SetMailSlotInfo" Function ulong ofx_CreateMailSlot(ref string lpName , & ulong nMaxMessageSize , & ulong lReadTimeout , & ulong lpSecurityAttributes) library "Kernel32.dll" alias for "CreateMailslotW" Function boolean ofx_GetMailSlotInfo ( ulong hMailslot , & ref ulong lpMaxMessageSize, & ref ulong lpNextSize , & ref ulong lpMessageCount , & ref ulong lpReadTimeout) library "kernel32.dll" alias for "GetMailslotInfo" Function ulong ofx_createFile ( string lpFileName , & ulong dwDesiredAccess , & ulong dwShareMode , & ulong lpSecurityAttributes , & ulong dwCreationDisposition, & ulong dwFlagsAndAttributes , & ulong hTemplateFile) library "kernel32.dll" alias for "CreateFileW" Function boolean ofx_ReadFile ( ulong hFile , & ref string lpBuffer , & ulong nNumberOfBytesToRead , & ref ulong lpNumberOfBytesRead , & ulong lpOverlapped) library "kernel32.dll" alias for "ReadFile" Function boolean ofx_writeFile ( ulong hFile , & ref string lpBuffer , & ulong nNumberOfBytesToWrite , & ref ulong lpNumberOfBytesWritten , & ulong lpOverlapped) library "kernel32.dll" alias for "WriteFile" end prototypes type variables Protected : // Chemin complet du slotMail qui a été créé par la présente classe // Affecté dans of_setpath() String is_pathMailSlot // Taille des message du mailSlot, ne peut être supérieur à i#_maxApiMessageSize // Affecté dans of_setpath() Long il_MailSlotMessageSize // Time out du mail slot // Affecté dans of_setpath() Long il_MailSlotIimeOut //Return values Constant integer i#_InvalidHandleValue = -1 //File access Constant ulong i#_genericRead = 2147483648 //0x80000000 Constant ulong i#_genericWrite = 1073741824 //0x40000000 //File shares Constant ulong i#_fileShareRead = 1 //Creation types Constant ulong i#_createAlways = 2 Constant ulong i#_openExisting = 3 //File attributes Constant ulong i#_fileAttributeNormal = 128 // Taille maximale des messages pour l'API window Constant Long i#_maxApiMessageSize = 65536; end variables forward prototypes public function boolean of_getmailslotinfo (unsignedlong aul_mslot, ref unsignedlong aul_maxmsg, ref unsignedlong aul_nextmsg, ref unsignedlong aul_msgcount, ref unsignedlong aul_timeout) public function boolean of_settimeout (unsignedlong aul_idslot, unsignedlong aul_timeout) public function integer of_sendmail (string as_path, string as_message) public function integer of_getcountslotmailmessage (unsignedlong aul_mslot) public function integer of_readmail (ref string as_message, long al_slotmailhandle) public function boolean of_mailslotexists (string as_path) public function boolean of_closemailslot (unsignedlong aul_slot) public subroutine of_setpath (string as_path, long al_mailslotmessagesize, long al_timeout) public function integer of_createmailslot () end prototypes event _commentaire();//------------------------------------------------------------------------------------------------------------------------------- // Objet : Classe qui dépose ou lit de l'information dans un fichier virtuel (mail slot) par rapport à un chemin // Cela permet une communication inter-application via des fichiers virtuels. //------------------------------------- // Principe de fonctionnement // - Un composant P crée deux instances de celle classe. // La première (C1) crée un mailslot "Powerbuilder", C1 est capable de lire et d'écrire dans ce dernier. // La seconde (C2) peut envoyer un message à un mail slot ouvert par un tiers issu ou non d'un environnement autre que PowerBuilder // Ainsi P à travers C1 peut envoyer un message dans le mailslot "PowerBuilder" // à travers C2 lire un message qui a été envoyé par un autre composant // Une communication bi directionnelle s'établit donc entre le composant P est un composant extérieur //---------------------------------------- // Remarque : La communication se fait en utilisant des fonctions de l'API Windows kernel32 // Documentation : http://msdn.microsoft.com/en-us/library/aa365147(VS.85).aspx) //--------------------------------------------------------------------------------------------------------------------------------- end event public function boolean of_getmailslotinfo (unsignedlong aul_mslot, ref unsignedlong aul_maxmsg, ref unsignedlong aul_nextmsg, ref unsignedlong aul_msgcount, ref unsignedlong aul_timeout);//--------------------------------------------------------------------------------------------------------------------------------- // Objet : Récupère des informations concernant le mailSlot //---------------------------------- // Paramètres : aul_mslot , identifiant du mailSlot // ref aul_maxmsg , nombre maximum de messages // ref aul_nextmsg , indicateur du prochain message // ref aul_msgcount , nombre de messages en attente // ref aul_timeout , timeout du mailSlot //---------------------------------- // Déclencheur : A la demande, routine de service //---------------------------------- // Code retour : true, la récupération des données du mails a réussie // false, impossible de récupérer les informations concernant le malislot //--------------------------------------------------------------------------------------------------------------------------------- Return ofx_GetMailSlotInfo (aul_mslot, ref aul_maxmsg, ref aul_nextmsg, ref aul_msgcount, ref aul_timeout) end function public function boolean of_settimeout (unsignedlong aul_idslot, unsignedlong aul_timeout);//--------------------------------------------------------------------------------------------- // Objet : Modifie le timeout du mailSlot //-------------------------------- // Paramètres : aul_idslot, identifiant du mailslot // aul_timeout, timeout que l'on souhaite passé au mailsolot //-------------------------------- // Déclencheur : A la demande, routine de service //------------------------------- // Code retour : retour de la fontion externe ofx_setMailSlotInfo() //------------------------------------------------------------------------------------------------ il_MailSlotIimeOut = aul_timeout Return ofx_setMailSlotInfo(aul_idslot, aul_timeout) end function public function integer of_sendmail (string as_path, string as_message);//------------------------------------------------------------------------------------------------------------------------------------------------- // Objet : Crée le mailslot s'il n'existe pas et écrit dans celui-ci. //---------------------------------- // Paramètres : as_path : chemin complet où se situe l emailslot // as_message : messahe a envoyer //---------------------------------- // Déclencheur : A la demande routine de service //---------------------------------- // Code retour : 1, l'écriture dans le mail slot a réussie // -1, l'écriture dans le mail slot a échoué ou n'a pas eut lieu // -2, le fichier associé au mailslot n'existe pas ou n'a pas pu être ouvert // -3, le message comporte trop de caractères // -4, le message ne comporte aucun caractère //------------------------------------------------------------------------------------------------------------------------------------------------- Boolean lb_retWrileFile = false // Code retour de ofx_writeFile() Ulong lul_retCreateFile // Identifiant du mailSlot, -1 si le mailslot n'a pu être crée Ulong lul_written // Paramètre attendu par ofx_writeFile If len(as_message) > il_MailSlotMessageSize then Return -3 End if If len(as_message) = 0 or isnull(as_message) then Return -4 End if lul_retCreateFile = ofx_createFile(as_path, i#_genericWrite, i#_fileShareRead, 0, i#_createAlways , i#_fileAttributeNormal, 0) Choose Case lul_retCreateFile Case i#_InvalidHandleValue Return -2 // Le fichier associé au mailslot n'existe pas ou n'a pas pu être ouvert Case else // Le mailslot existe ou a été créé lb_retWrileFile = ofx_writeFile( lul_retCreateFile, as_message, len(as_message) * 2, Ref lul_written, 0) ofx_closeHandle(lul_retCreateFile) If lb_retWrileFile then Return 1 // Message envoyé Else Return -1 // Message non envoyé End If End Choose end function public function integer of_getcountslotmailmessage (unsignedlong aul_mslot);//--------------------------------------------------------------------------------------------------------------------------------- // Objet : Retourne le nombre de messages en attente dans le mailSlot //---------------------------------- // Paramètres : aul_mslot , identifiant du mailSlot //---------------------------------- // Déclencheur : A la demande, routine de service //---------------------------------- // Code retour : Nombre de message en attente // -1 si une erreur est survenue //--------------------------------------------------------------------------------------------------------------------------------- Ulong lul_msgcount // Nombre de message en attente Ulong lul_maxmsg, lul_nextmsg, lul_timeout // Paramètres nécessairse à la fonction of_getMailslotInfo() If of_getmailslotinfo( aul_mslot, ref lul_maxmsg, ref lul_nextmsg, ref lul_msgcount, ref lul_timeout) then Return lul_msgcount Else Return -1 End if end function public function integer of_readmail (ref string as_message, long al_slotmailhandle);//----------------------------------------------------------------------------------------------------------------------------------------------------- // Objet : Lit le prochain message dans la file d'attente du mailslot //------------------------------- // Paramètre : ref as_message, message lu //------------------------------- // Déclencheur : A la demande, routine de service //------------------------------- // Code retour : 1, le message a été correctement lu // 0, aucun message n'a été lu // -1, une erreur est survenu ne permettant pas de lire le message //----------------------------------------------------------------------------------------------------------------------------------------------------- Ulong lul_maxMessageSize // Longueur maximum du message Ulong lul_nextMessageSize // Number of bytes to be read from the file. Ulong lul_messageCount // Nombre de message dans la file d'attente du mailSlot Ulong lul_timeout // TimeOut défini pour le mailSlot Ulong lul_read // Longueur du message lut of_getmailslotinfo( al_slotmailhandle, ref lul_maxMessageSize, ref lul_nextMessageSize, ref lul_messageCount, ref lul_timeout) If lul_messageCount > 0 then as_message = space(lul_nextMessageSize / 2) else Return 0 End if If ofx_readFile( al_slotmailhandle, ref as_message, lul_nextMessageSize, ref lul_read, 0) = false then Return -1 Else Return 1 // le message a été correctement lu (test nécessaire : lul_read = lul_nextMessageSize ?) End if end function public function boolean of_mailslotexists (string as_path);//--------------------------------------------------------------------------------------------------------------------------- // Objet : Test l'existence du mail slot //--------------------------- // Paramètres : as_path, chemin complet du mailslot // as_fileHandle, idenfiant du fichier virtuel //-------------------------- // Déclencheur : A la demande routine de service //-------------------------- // Code retour : true, le mailslot existe // false, le maislot n'existe pas //--------------------------------------------------------------------------------------------------------------------------- Long ll_fileHandle // Identifiant du fichier virtuel ll_fileHandle = ofx_createFile(as_path, i#_genericRead + i#_genericWrite, i#_fileShareRead, 0, i#_openExisting, 0, 0) If ll_fileHandle = i#_InvalidHandleValue Then Return False ofx_closeHandle(ll_fileHandle ) Return true end function public function boolean of_closemailslot (unsignedlong aul_slot);//------------------------------------------------------------------------------------------------------------------------------------------ // Objet : Fermeture du mailslot. //-------------------------------- // Déclencheur : A la demande, routine de service //------------------------------- // Paramètre : aul_slot, identifiant du canal de communication //------------------------------- // Code retour : true , fermeture réussie // false , échec //------------------------------------------------------------------------------------------------------------------------------------------ Return ofx_closeHandle(aul_slot) end function public subroutine of_setpath (string as_path, long al_mailslotmessagesize, long al_timeout);//--------------------------------------------------------------------------------------------------------------------------- // Objet : Affecte les propriétés du mailslot, chemin, taille et timaout //--------------------------- // Paramètres : as_path , chemin complet du slotMail qui va être créé par la présente classe // al_mailslotmessagesize , taille que l'on veut affecter au mailslot // al_timeout , temps pour le time out du mail slot //-------------------------- // Déclencheur : Suite à l'instanciation de la classe //--------------------------------------------------------------------------------------------------------------------------- is_pathMailSlot = as_path il_MailSlotIimeOut = al_timeout If al_mailslotmessagesize > i#_maxApiMessageSize or al_mailslotmessagesize < 1 then il_MailSlotMessageSize = i#_maxApiMessageSize Else il_MailSlotMessageSize = al_mailslotmessagesize End if end subroutine public function integer of_createmailslot ();//------------------------------------------------------------------------------------------------------------------------------------------ // Objet : Création du canal de communication //-------------------------------- // Déclencheur : A la demande routine de service //------------------------------- // Paramètres : aul_maxsize , taille maximale pour le mailslot // aul_timeout , timeOut pour le mailslot //------------------------------- // Code retour : le handle du mailslot // -1, la création a échoué //------------------------------------------------------------------------------------------------------------------------------------------ Integer li_ret // Code retour de ofx_CreateMailSlot() li_ret = ofx_CreateMailSlot( ref is_pathMailSlot, il_MailSlotMessageSize, il_MailSlotIimeOut, 0) Return li_ret end function on nvo_mailslot.create call super::create TriggerEvent( this, "constructor" ) end on on nvo_mailslot.destroy TriggerEvent( this, "destructor" ) call super::destroy end on
Dernière modification par Dadone (03-10-2013 07:33:49)
Hors ligne
Dadone a écrit:
entièrement commenté et légèrement amendé...
Commenté, effectivement pas difficile d'améliorer ce qui a commencé comme un "proof of concept" pour voir si on pouvait dialoguer simplement entre 2 applis PB (ou dans mon ca entre PB et Java) sur une plateforme windows.
Par contre serait-il possible d'avoir la liste de ce qui a été ajouté / amélioré / corrigé ?
Dernière modification par seki (03-10-2013 09:04:33)
Hors ligne
seki a écrit:
Par contre serait-il possible d'avoir la liste de ce qui a été ajouté / amélioré ?
Ce qui a été ajouté influe sur la manière dont va être utilisée la classe qui devient une "boite noire".
Par exemple le chemin est passé en argument à la classe ainsi que la taille maximale des messages ainsi que le time out.
Si rien n'est passé à la classe (sauf le chemin, obligatoire) alors on a des constantes par défaut.
Dans le même état d'esprit certains codes retours sont plus riches pour que le composant appelant sache où est le problème.
Au final, rien de transcendant simplement cette classe n'est plus une démonstration de faisabilité ("proof of concept") mais un composant aboutit de niveau professionnel directement utilisable.
Avec ton implémentation en JAVA, on a trois classes qui permettent à trois environnements différents de communiquer.
Dernière modification par Dadone (03-10-2013 10:52:46)
Hors ligne