IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langages de programmation Discussion :

[conseils] XPCOM/COM autres technos?


Sujet :

Langages de programmation

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau membre du Club
    Inscrit en
    Septembre 2009
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Septembre 2009
    Messages : 5
    Par défaut [conseils] XPCOM/COM autres technos?
    Bonjour,

    Il y a deja quelque temps j'ai decouvert ce qu'est reellement la technologie XPCOM de Mozilla Foundation. Suite a ca, j'ai commence a m'interesser vraiment au developpement par composant et j'ai donc egalement lu quelques articles sur la technologie COM de microsoft, et cherche des alternatives.

    Je ne suis pas completement satisfait des solutions que j'ai vu jusqu'a present (XPCOM, COM, ICE?)

    Je parle principalement de la mise en place du programme et des librairies fournies.
    Corrigez moi si je me trompe (c'est pour recevoir des commentaires que je poste en fait)mais voici ce que j'en retiens:

    Pour utiliser le "pattern" de developpement par composant, on a besoin de que notre runtime:
    1. Permette de charger la DLL specifiee(ou autre "fichier composant").
    2. Permette d'instancier une classe depuis la DLL chargee.
    3. Permette de decharger la DLL specifiee.

    Donc en gros l'interface pour recuperer un composant inconu pour reprendre les termes COM:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public interface IComponentFactory
    {
      Object getInstance(Object param,string[] expectedInterfaces);
    }
    Et nos composants
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public interface IComponent
    {
       string[] getInterfaces();
       void CastTo(String s)
       {
          if( !getInterfaces().contains(s) )
          {
             throw( new InvalidCastException(); )
          }
       };
    }
    On donne meme la possibilite a lutilisateur de passer des parametres a la creation.

    Puis dans notre runtime on propose les fonctions statiques:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public static String Components.GetClass(Class c);
    public static IComponent Components.Load(String file);
    public static void Components.Unload(String file);
    public static void Components.Unload(IComponent compfactory);
    En gros on peut charger les composants en indiquant le fichier a partir duquel charger tout simplement, et on peut liberer la memoire quand approprie soit en passant le path/name du fichier, soit en passant l'objet charge (qui agit comme une factory pour les composants).

    La fonction Load se charge de charger la DLL de facon a ce que les objets crees puissent etre castes correctement ds le langage ds lequel nous sommes.

    Imaginons qu'on aie un objet TCPServer dans le fichier "TCPServer.dll" et que notre composant prennent en entree un objet IPEndPoint

    On veut pouvoir ecrire un code du genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    // fichier de declaration pour les interfaces implementees par MyServer
    // header en C++, cs in csharp par example etc...
    // La definition est partagee entre les composants clients
    // et l'implementation
    namespace SharedNamespace
    {
    	// Une interface implementee par un composant
    	public interface IOtherInterface
    	{
    		public virtual void OherMethod();
    	}
    
    	// Une interface implementee par un composant
    	public interface IMyServer
    	{
    		public virtual void DoSomeStuff();
    	}
    }
    
    //fichier source pour MyServer
    namespace ComponentNamespace
    {
    	using namespace TCPServerns;
    	using namespace MyCOMns;
    	using namespace SharedNamespace;
    	// Implementation du composant derive toujours de IComponent
    	// Aucune classe cliente n'a besoin de connaitre cette classe
    	protected class MyServer : IMyServer, IOtherInterface, IComponent
    	{
    		private ITCPServer server;
    		private IComponentFactory TCPserverFactory;
    		
    		// derive de IComponent
    		public static override string[] getInterfaces()
    		{
    			string[] ifs = new string[2];
    			ifs[0] = MyCOM.getClassName(IMyServer);
    			ifs[1] = MyCOM.getClassName(IOtherInterface);
    		}
    		
    		// derive de IOtherInterface
    		public override void OherMethod(){return;}
    		
    		// derive de IMyServer
    		public override void DoSomeStuff(){return;}
    		
    		// creation
    		public MyServer(Object o)
    		{
    			this.TCPserverFactory = Components.Load("TCPServer.dll")
    			IPEndPoint ipep = new IPEndPoint(...);
    			string[] expectedif = new string[1];
    			expectedif[0] = "TCPServer";
    			this.server= (ITCPServer)TCPServerFactory.getInstance(ipep,expectedif);
    		}
    	}
    	
    	public class MyServerFactory : IComponentFactory
    	{
    		private string[] interfaces = null;
    		
    		public override Object getInstance(Object o, string[] expected)
    		{
    			this.check(expected,MyServer.getInterfaces());	//renvoie une exception si on ne connait pas l'interface demandee...
    			return (new MyServer());
    		}
    	}
    }
    }
    
    //fichier source pour le main de l'appli, qui est aussi notre client...
    namespace Clientns
    {
    	using namespace MyCOMns;
    	using namespace SharedNamespace;
    
    	public class MyMain
    	{
    		public void Main()
    		{
    			IComponentFactory MyServerFactory = Components.Load("MyServer.dll")
    			string[] expectedif = new string[1];
    			expectedif[0] = "IMyServer";
    			IMyServer server= (IMyServer)MyServerFactory.getInstance(null,expectedif); 
    			server.DoSomeStuff();
    			IOtherInterface OtherShape = (IOtherInterface)server.CastTo(MyCOM.getClassName(IOtherInterface));
    			return;
    		}
    	}
    }
    Voila, ca m'a l'air tout a fait possible, et pas besoin de methodes du genre de "AddRef", ou "Release", comme defini par .COM par example.
    On laisse l'utilisateur gerer ses objets comme il a l'habitude de le faire dans son language. On lui permet juste de charger dynamiquement certains modules...

    Ca me parrait legerement plus simple que XPCOM ou .COM comme approche, non?

    En gros ca necessiterait que nos DLL soient accompagnees d'un fichier descriptif pour savoir ou sont les methodes a aller chercher...

    Mais ca a l'air completement faisable de generer ca directement depuis le code(avant ou apres compilation). en regardant de quelles interfaces derive l'objet qui derive de IComponent....

    En fait l'idee c de simplifier les choses en se passant de fichier IDL par exemple. Les languages de programmations nous permettent de definir des classes "interfaces", donc il suffirait de generer le fichier IDL a partir du code en lui meme.

    Donc en gros 3 simplifications par rapport a XPCOM et COM:
    - pas de fichier IDL
    - pas de gestion mysterieuse de la memoire. La memoire est geree par l'utilisateur comme il en a l'habitude...
    - pas de librairie par defaut: le runtime se contente d'etre capable de charger les composants. Un point c'est tout.

    L'idee est que je trouve COM tres intrusif dans la facon d'ecrire le code apres coup...
    XPCOM m'a l'air tres proche de ca, neanmoins ils ont besoin d'IDL... Mais c'est peut etre la solution?
    Mais j'ai vu pas mal de critiques d'XPCOM sur certains forums... Alors qu'en y repensant j'ai vraiment l'impression que ce sont eux qui tiennent le bon bout a l'heure actuelle?

    Quelqu'un aurait-il une solution meilleure que XPCOM a proposer pour la base d'un programme ecrit par composants?

    Aussi la distribution d'XPCOM que j'ai touve vient avec XULRunner (pour l'instant c'est ce que j'en ai vu), donc on se prend des milliards de classes dont on n'a pas forcement besoin pour n'importe quelle application lambda.

    De la meme facon, ICE a l'air de venir en bloc si on peut se permettre le jeu de mot, donc on compile contre des librairies deja orientee communication, alors que je veux juste compiler contre des librairies qui me permettent de charger des composants (et ensuite charger eventuellement des composants responsables de gerer les communications....)

    Merci d'avance pour vos conseils...

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 398
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 398
    Par défaut
    Si l'utilisateur doit choisir lui-même quand charger et décharger la DLL, c'est trop compliqué. CoGetClassObject() et CoCreateInstance() chargent automatiquement la DLL, et CoFreeUnusedLibraries() les décharges après avoir interrogé les DLLs par DllCanUnloadNow().

    pas de gestion mysterieuse de la memoire. La memoire est geree par l'utilisateur comme il en a l'habitude...
    La gestion manuelle est plus compliquée et plus susceptible d'erreurs que le comptage de références. Si tu veux éviter les addref/release, utilise des pointeurs intelligents (ou un runtime qui gère ça de lui-même, comme .Net)
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    Citation Envoyé par florian.g Voir le message
    De la meme facon, ICE a l'air de venir en bloc si on peut se permettre le jeu de mot, donc on compile contre des librairies deja orientee communication, alors que je veux juste compiler contre des librairies qui me permettent de charger des composants (et ensuite charger eventuellement des composants responsables de gerer les communications....)
    D'un autre côté, as-tu bien compris ce qui se cachait derrière l'acronyme ICE ??? Internet Communication Engine...

    Certes, tu peux aussi avoir des endpoints locaux avec ICE (c'est à dire que la communication ne se fait pas par réseau, mais "directement" dans le code applicatif ICE), ou sur la boucle locale du PC (pour l'inter-processus). Ce n'est pas le cas nominal et idéal, par contre.

    Si tu veux une approche "plugin", mais SANS communication, je te conseillerais plutôt d'aller voir du côté de POCO, pour la portabilité, ou effectivement de rester sur COM si seul le monde Windows t'intéresse.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  4. #4
    Nouveau membre du Club
    Inscrit en
    Septembre 2009
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Septembre 2009
    Messages : 5
    Par défaut
    Merci pour vos reponses!

    @MacLAK
    En fait oui je sais ce que veut dire ICE, mais au dela de l'acronyme, si tu lis le manuel tu verras que c'est une approche de la programmation par composant d'un certain point de vue. Les composants sont juste distribues sur le reseau.
    Et d'ailleurs en regardant un peu plus profondement, ICE propose le service ICEbox, qui permet de charger des composants locaux.

    On peut lire dans la description de ICEBox:
    Application components can be deployed as dynamic library instead of as a process.
    On parle clairement de developpement par composant.

    Mais de mon point de vue il y a une erreur dans le sens dans le quel est pris le probleme:
    Ce n'est pas la partie communication qui choisit de charger un composant, c'est bien le composant qui peut choisir de charger UNE facon de communiquer.
    ICEBOX devrait etre au coeur du systeme ICE, et pas l'inverse.

    Une grosse partie de ICE est de definir un protocole de communication pour realiser des RPC/RMI etc...
    Mais ils presentent une excellente partie de ce qui devrait etre au coeur de nimporte quelle application en fait (n'importe quelle appli qui ne fonctionne pas en otiste).

    En fait je ne reproche que 2 choses pour rendre le modele plus general:
    - Inverser la relation composant/communication engine: Un communication engine peut etre charge et utilise comme un autre composant.
    - Proposer de charger le support TCP/IP-UDP-Serie-Pipes comme n'importe quelle autre composant.

    Je pense qu'au dela de ca l'approche est par ailleurs excellente.

    Je parle en fait de l'architecture de base d'une application en general. On pourrait quand meme avoir a notre epoque un moyen d'ecrire une application portable et modulaire sans redefinir a chaque fois son propre format de DLL et ses factories pour les modules... Ce sont quand mme des concepts tres generaux...

    Pareil ICE propose un Marshaling des donnees qui a l'air implante comme une partie indisecable de l'appli. Et si l'utilisateur veut utiliser les protocoles de RMI/RPC de ICE sur le format de donnees de Protocole Buffers?

    Si le marshalling par defaut de ICE n'est pas suffisament efficace pour une raison X ou Y, on jette le package? Par example, si on serialize nos donnees de facon customisee, on se trimbale la serialization par defaut sans l'utiliser.

    De la meme facon, si on ne communique pas par dessus un reseau LAN, mais par dessus un port serie ou un bus CAN par example... la aussi on trimbale une librairie TCP/IP qu'on ne va pas utiliser...

    Il y a certains points comme ca ou un poil plus d'abstraction aurait peut etre aide?

    En fait je bosse sur de l'embarque, donc je ne peux pas toujours me permettre (niveau memoire notament) d'inclure des bouts de librairies que je n'utilise pas.
    L'idee est de ne pas avoir un noyau qui fait 3 fois la taille de ce qu'il pourrait faire...

    Pour resumer sur ICE, ICE propose bien plus qu'un simple outil de communication.

    @medinoc:
    La gestion intelligente de la memoire peut etre implementee comme un composant. Ce serait bien de pouvoir choisir de l'utiliser ou pas selon nos besoin, et de changer l'implementation selon nos besoins aussi, non?
    Je cherche peut etre "trop" modulable?
    Pourtant ca ne me parait pas absurde.
    En tous cas, la gestion intelligente de la memoire impacte les performances, donc sur certains systemes embarques, on aimerait s'en passer.
    Comme je parle de systemes qui discutent eventuellement avec des ordis, c la ou se trouve l'interet de supporter des protocoles de communication bien generaux comme ceux implementes par ICE...

    Encore une fois merci pour vos reponses. Personellement a force d'en discuter avec pas mal de gens jai fini par bien identifier de quoi nous avons besoin exactement.

  5. #5
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    IceBox, en soi, n'a presque aucun intérêt : le noeud, c'est IceGrid. C'est ce composant qui permet de correctement référencer les endpoints.

    Côté communication, relis l'acronyme... Tu verras pourquoi c'est TCP/IP qui est privilégié ! Il existe toutefois une version embedded de ICE. Par rapport aux divers média possibles, il n'y a pas de besoin réel.

    Je bosse aussi dans l'embarqué, mais je n'utilise pas ICE pour les parties RT. C'est surtout pour la com haut niveau, le bas niveau utilisant plus IceStorm que Ice "brut".

    Toutefois, rien ne t'empêche d'utiliser un endpoint Ice pour piloter un capteur sur une LS ou un bus de terrain. Mais ne confonds pas un bus logiciel distribué comme ICE avec un bus matériel comme CAN : l'association / pont entre les deux ne sera pas automatique.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  6. #6
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 398
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 398
    Par défaut
    En tous cas, la gestion intelligente de la memoire impacte les performances, donc sur certains systemes embarques, on aimerait s'en passer
    Franchement, je pense que le comptage de références, ça ne consomme rien par rapport à un GC.

    Et puis, si tu veux t'en passer, tu peux juste garder UNE référence et utiliser des pointeurs "bêtes" pour le reste. COM a tendance à se passer des AddRef() pour les simples appels de fonction, ne les utilisant que quand il faut stocker une référence quelque part.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Nouveau membre du Club
    Inscrit en
    Septembre 2009
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Septembre 2009
    Messages : 5
    Par défaut
    @Medinoc
    Mais oui, tu as raison jai dit une annerie. Si la gestion de la memoire se fait par comptage des references en effet ca n'a quasi-aucun impact.
    Tres bonne idee en fait donc des smart pointers pour gerer la memoire... je comprends mieux l'interface proposee par COM en fait merci. C'est stupide, c'est comme quand on cherche des lunettes alors qu'on les a sur le nez...

    @MacLAK
    Je comprends bien ce que tu dis, on est presque sur la meme longueur d'onde en fait.
    Je pense par contre que en effet ICEBox ne contient pas "l'intelligence" du systeme, mais que ca devrait justement etre au coeur du systeme. Tres peu d'intelligence, donc une librairie de base tres legere, mais des possibilites infinies.
    Cette capacite a charger des composants locaux est la part la plus essentielle de toute application (je parle de maniere generale, la part la plus reutilisable, et qui peur accelerer enormement le developpement).

    Ensuite en chargeant les composants qui implementent les interfaces qu'il faut on peut faire de la communication comme on veut.
    Pour le fait que I de Ice soit "Internet", oui je sais bien, mais c'est juste un acronyme qui est loin de refleter les possibilites qui sont derriere.
    Et on gagnerait surement a pouvoir implementer des composants qui implementent d'autres protocoles que TCP/IP UDP etc... et a pouvoir egalement enlever TCP/IP si on en a pas besoin dans un cas particulier...
    Par exemple on pourrait imaginer ce type d'appel:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ic‑>createObjectAdapterWithEndpoints(
                    "Example", "serial ‑p COM1");
    En implementant l'interface necessaire, on devrait pouvoir fournir notre protocole "serial" de communication.

    Pour repondre a mon interrogation premiere, je vais sticker avec Ice(-E) pour un moment, et voir si c'est reellement aussi simple et pratique que ca m'en a l'air.

    Merci encore pour vos reponses, c'etait tres interessant.
    :

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 3
    Dernier message: 22/03/2010, 11h10
  2. [Toutes versions] IHM avec autres technos ?
    Par jax54000 dans le forum IHM
    Réponses: 10
    Dernier message: 18/11/2009, 10h20
  3. [Forms] : passage en J2E ou autres technos
    Par Nargel33 dans le forum Forms
    Réponses: 6
    Dernier message: 18/06/2007, 17h38

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo