Certains langages de programmation offrent ce type de fonctionnalité, notamment Smalltalk, Java et C#, qui fournissent des outils pour connaître et utiliser la classe d'un objet, ses propriétés et ses méthodes (on parle en général de méta-classe, de méta-propriété et de méta-fonction).
L'introspection peut être utilisée pour fournir des bindings vers des langages de script, pour écrire des éditeurs de propriétés, ou faire de la sérialisation. L'intérêt étant que le code de ces outils est écrit une fois pour fonctionner sur la structure abstraite (méta-classe, méta-propriété, méta-fonction), et peut ensuite être utilisé dans n'importe quel programme.
Malheureusement, le langage C++ ne fournit aucun moyen de faire de la réflexion. Il existe cependant un certain nombre de bibliothèques fournissant ce type de fonctionnalité, la plus connue étant probablement Qt avec ses QObjects.
Cependant, pour générer toutes les « méta-informations » nécessaires à la réflexion, la majeure partie de ces bibliothèques requiert soit d'utiliser un pré-compilateur (moc pour Qt), soit de déclarer ses informations en ajoutant tout un tas de macros dans l'en-tête de chaque classe ; C++ Mirror faisant exception. De plus, il est souvent nécessaire d'hériter d'une classe de base (QObject pour Qt).
Ceci a amené Tegesoft à développer CAMP, une bibliothèque de réflexion généraliste pour C++. CAMP utilise intensivement les templates C++, ainsi que boost (ensemble de bibliothèques C++ permettant d'étendre les fonctionnalités du langage). Il est non-intrusif, à l'exception de la gestion du polymorphisme pour les méta-classes ; une alternative basée sur le RTTI (Run-Time Type Information : fait de déterminer, à l'exécution du programme, le type d'une variable, dans les langages orienté-objet) du langage devrait être ajoutée dans la prochaine version.
CAMP ressemble à Luabind ou à boost::python, mais est généraliste. De ce fait, il est possible d'écrire un module pour CAMP permettant d'embarquer un interpréteur Python, un autre pour embarquer un interpréteur Lua, ou encore un pour faire de la sérialisation XML, l'intérêt étant que le binding des classes n'est fait ici qu'une seule fois. Lorsqu'un nouveau module pour CAMP est disponible, vous n'avez aucun binding supplémentaire à écrire.
Le mieux dans tout ça ? C'est sous LGPL ! La version 0.6.0 de CAMP était déjà distribuée sous GPL, mais une licence plus permissive a été choisie afin de favoriser l'utilisation de la bibliothèque.
De plus, un nouveau site internet (basé sur Redmine) est disponible, avec bug tracker, wiki, et documentation de l'API. Le code est quant à lui hébergé sur GitHub. Un forum est également disponible.
Aller plus loin
- Site du projet (405 clics)
- Forum du projet (61 clics)
- Code source sur GitHub (136 clics)
- Site de Tegesoft (112 clics)
- Journal à l'origine de la dépêche (26 clics)
# Intéressant !
Posté par DLFP est mort . Évalué à 8.
DLFP >> PCInpact > Numerama >> LinuxFr.org
[^] # Re: Intéressant !
Posté par Damien (site web personnel) . Évalué à 4.
[^] # Re: Intéressant !
Posté par Gniarf . Évalué à 2.
ce qui manque à C++ c'est pouvoir créer une nouvelle classe de toutes pièces, en créant une classe Class qui s'appellera prout, qui aura un attribut (membre) public qui s'appellera totoz qui sera un entier ou un Troll, une méthode qui s'appellera coin et prendra Pan comme argument...
Java fait ça très simplement et dynamiquement (à l'execution, tu peux donner les noms de classes ou d'attributs à ce moment et les classes puis objets créés seront absolument comme les autres)
[^] # Re: Intéressant !
Posté par Gof (site web personnel) . Évalué à -1.
[^] # Re: Intéressant !
Posté par viridis (site web personnel) . Évalué à 6.
- xcpprefl : utilise un pré-compilateur, mais semble pas mal
- agm::libreflection : grosses macros qui tachent, directement dans la classe en plus
- boost::mirror : grosses macros qui tachent (un petit appercu), pas directement dans la classe cependant
- xrtti : utillise un pré-compilateur
- open-c++ : utilise un pré-compilateur
(Si tu connais d'autres bibliothèques, merci de me le indiquer, ça m'intéresse!)
Le problème du pré-compilateur, en plus de complexifier la chaîne de compilation, c'est qu'on ne peut pas choisir ce qu'on veut exporter et ce qu'on ne veut pas (ce qui est une nécessité pour nous) sans ajouter des informations à la main. Du coup, quitte à déclarer quelque chose, autant que ce soit le binding plutôt que d'utiliser un outil supplémentaire.
En ce qui concerne l'avantage des templates par rapport aux macros, c'est qu'on peut déterminer plus de chose à la compilation (genre les types, les nombres d'arguments, les const/non const...). Du coup, il y a beaucoup moins de chose à déclarer lors du binding.
[^] # Re: Intéressant !
Posté par viridis (site web personnel) . Évalué à 5.
- xpprefl : http://www.extreme.indiana.edu/reflcpp/
- agm::libreflection : http://www.codeproject.com/kb/library/libreflection.aspx
- boost:: mirror : http://kifri.fri.uniza.sk/~chochlik/mirror-lib/html/index.ht(...)
- xrtti : http://www.ischo.com/xrtti/documentation.html
- open-c++ : http://opencxx.sourceforge.net/occ-core/
[^] # Re: Intéressant !
Posté par Sebastien . Évalué à 1.
au-dela de pouvoir creer des bindings automatiquement pour des langages de haut niveau, c'est aussi utilise pour automatiquement enregistre sur disque (serialization) n'importe quelle instance de classe qui est connue.
Reflex: http://root.cern.ch/drupal/content/reflex
[^] # Re: Intéressant !
Posté par viridis (site web personnel) . Évalué à 3.
Ceci dit je suis curieux de savoir à quoi ça pourrait bien servir concrètement. C'est juste histoire de me coucher moins bête ce soir :)
[^] # Re: Intéressant !
Posté par chimrod (site web personnel) . Évalué à 1.
[^] # Re: Intéressant !
Posté par Gof (site web personnel) . Évalué à 3.
[^] # Re: Intéressant !
Posté par djano . Évalué à 2.
L'intérêt de ne pas générer de code permet de garder la base de code petite et aussi de ne pas ralentir la compilation (Ce qui fait perdre du temps aux devs). Ceci dit, on en paye inévitablement le prix lors de l'exécution.
Est ce que ce prix est acceptable? Aux utilisateurs de trancher.
Ça me fait penser au bon vieux troll langages dynamiques contre langages compilés.
[^] # Re: Intéressant !
Posté par Moonz . Évalué à 2.
class TypedArray < Array
class << self
attr_accessor :method
end
def <<(item)
if !item.responds_to? self.class.method
raise "#{item} does not respond to #{self.class.method}"
end
super
end
Qui s’utilise comme ça
ArrayDelegate = Class.new TypedArray
ArrayDelegate.method = :delegate=
my_array = ArrayDelegate.new
my_array.is_a? ArrayDelegate # Et ne doit pas répondre oui pour une autre sous-classe de TypedArray, comme un ToStringArray
[^] # Re: Intéressant !
Posté par viridis (site web personnel) . Évalué à 1.
[^] # Re: Intéressant !
Posté par whity . Évalué à 2.
La réflexion répond à certains besoins bien particuliers (le plus généralement : génération dynamique d'interfaces graphiques, plugins). Camp (de ce que j'en ai vi, je n'ai jamais pu la mettre en œuvre) est une excellente bibliothèque pour faire de la réflexion. Ca ne veut pas dire qu'il faut l'utiliser là où ça ne sert à rien :).
Mes commentaires sont en wtfpl. Une licence sur les commentaires, sérieux ? o_0
[^] # Re: Intéressant !
Posté par djano . Évalué à 2.
Rien ne te dit qu'il a eu le choix du langage. Et même s'il l'a eu, peut être qu'il préfère Ruby quand même.
[^] # Re: Intéressant !
Posté par Moonz . Évalué à 2.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.