Quoi, tu ne connais pas PB ? Va falloir parcourir tout le forum alors !

Le forum (ô combien francophone) des utilisateurs de Powerbuilder.

Recherche rapide

Annonce

Certaines rubriques, dont des cours, sont uniquement visibles par les membres du forum ^^.
Dans la rubrique Liens & Références, vous avez accès à un sommaire de téléchargement, profitez-en !
Il existe maintenant un nouveau TOPIC "Votre CV en Ligne" accessible uniquement par demande.

#1 02-10-2013 14:40:11

Dadone  
Membre Power Geek
Lieu: Avon (Seine et Marne)
Date d'inscription: 19-02-2007
Messages: 252
Pépites: 985
Banque: 0
Site web

Mail Slot

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#

Code: pb

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

 

#2 03-10-2013 08:27:29

seki  
0x73656B69
Award: bf
Lieu: Laquenexy & Luxembourg
Date d'inscription: 20-11-2008
Messages: 1118
Pépites: 4,296,080,204
Banque: 9,223,372,036,854,776,000
Site web

Re: Mail Slot

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)


The best programs are the ones written when the programmer is supposed to be working on something else. - Melinda Varian

Mes réponses PB sur StackOverflow
http://stackoverflow.com/users/flair/317266.png

Hors ligne

 

#3 03-10-2013 08:56:31

Dadone  
Membre Power Geek
Lieu: Avon (Seine et Marne)
Date d'inscription: 19-02-2007
Messages: 252
Pépites: 985
Banque: 0
Site web

Re: Mail Slot

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

 

Pied de page des forums

Propulsé par FluxBB 1.2.22