|
@@ -0,0 +1,117 @@
|
|
|
+Le principal de l'architecture actuelle de VLC est organisé autour de la notion
|
|
|
+de module. D'un côté, le core contrôle le chargement des fonctionnalités et joue
|
|
|
+un rôle d'orchestrateur. De l'autre côté chaque fonctionnalité est apportée par
|
|
|
+un module qui peut être chargé dynamiquement ou lié statiquement à
|
|
|
+l'application.
|
|
|
+
|
|
|
+Les modules sont manipulés à travers les \inltype{vlc_plugin_t} qui eux-même
|
|
|
+manipulent les \inltype{module_t} contenant la représentation interne du module.
|
|
|
+
|
|
|
+\begin{code}{c}{Structure d'un plugin}
|
|
|
+typedef struct vlc_plugin_t
|
|
|
+{
|
|
|
+ struct vlc_plugin_t *next;
|
|
|
+ module_t *module;
|
|
|
+ unsigned modules_count;
|
|
|
+
|
|
|
+ const char *textdomain; /**< gettext domain (or NULL) */
|
|
|
+
|
|
|
+ /* Variables set by the module to store its config options */
|
|
|
+ struct
|
|
|
+ {
|
|
|
+ module_config_t *items; /**< Table of configuration parameters */
|
|
|
+ size_t size; /**< Size of items table */
|
|
|
+ size_t count; /**< Number of configuration items */
|
|
|
+ size_t booleans; /**< Number of booleal config items */
|
|
|
+ } conf;
|
|
|
+
|
|
|
+#ifdef HAVE_DYNAMIC_PLUGINS
|
|
|
+ bool unloadable; /**< Whether the plug-in can be unloaded safely */
|
|
|
+ atomic_uintptr_t handle; /**< Run-time linker handle (or nul) */
|
|
|
+ char *abspath; /**< Absolute path */
|
|
|
+
|
|
|
+ char *path; /**< Relative path (within plug-in directory) */
|
|
|
+ int64_t mtime; /**< Last modification time */
|
|
|
+ uint64_t size; /**< File size */
|
|
|
+#endif
|
|
|
+} vlc_plugin_t;
|
|
|
+\end{code}
|
|
|
+
|
|
|
+\inltype{vlc_plugin_t} contient ainsi les informations pour charger et décharger
|
|
|
+les modules.
|
|
|
+
|
|
|
+\begin{code}{c}{Structure d'un module}
|
|
|
+struct module_t
|
|
|
+{
|
|
|
+ vlc_plugin_t *plugin; /**< Plug-in/library containing the module */
|
|
|
+ module_t *next;
|
|
|
+
|
|
|
+ /** Shortcuts to the module */
|
|
|
+ unsigned i_shortcuts;
|
|
|
+ const char **pp_shortcuts;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Variables set by the module to identify itself
|
|
|
+ */
|
|
|
+ const char *psz_shortname; /**< Module name */
|
|
|
+ const char *psz_longname; /**< Module descriptive name */
|
|
|
+ const char *psz_help; /**< Long help string for "special" modules */
|
|
|
+
|
|
|
+ const char *psz_capability; /**< Capability */
|
|
|
+ int i_score; /**< Score for the capability */
|
|
|
+
|
|
|
+ /* Callbacks */
|
|
|
+ const char *activate_name;
|
|
|
+ const char *deactivate_name;
|
|
|
+ void *pf_activate;
|
|
|
+ void *pf_deactivate;
|
|
|
+};
|
|
|
+\end{code}
|
|
|
+
|
|
|
+De l'autre côté, \inltype{module_t} est réellement la description d'un module.
|
|
|
+
|
|
|
+Chaque module dispose d'une priorité, qui correspond au score \inltype{i_score}
|
|
|
+dans \inltype{module_t}.
|
|
|
+
|
|
|
+Ces modules sont chargés dans l'application depuis deux fonctions du core:
|
|
|
+\begin{itemize}
|
|
|
+ \item \inltype{module_need} permet de charger un module correspondant au nom ou à la
|
|
|
+fonction \inltype{i_capability} du module, en utilisant le premier module de plus forte
|
|
|
+priorité qui est capable de se charger sans erreur.
|
|
|
+ \item \inltype{module_need_var} qui dans les faits appelle \inltype{module_need} en lui donnant le
|
|
|
+contenu d'une variable au lieu d'une recherche hardcodée.
|
|
|
+\end{itemize}
|
|
|
+
|
|
|
+\begin{code}{c}{Création d'objet VLC puis chargement de modules}
|
|
|
+ /* from src/misc/xml.c */
|
|
|
+ p_xml = vlc_custom_create( p_this, sizeof( *p_xml ), "xml" );
|
|
|
+ p_xml->p_module = module_need( p_xml, "xml", NULL, false );
|
|
|
+
|
|
|
+ reader = vlc_custom_create(obj, sizeof(*reader), "xml reader");
|
|
|
+ reader->p_module = module_need(reader, "xml reader", NULL, false);
|
|
|
+\end{code}
|
|
|
+
|
|
|
+Par exemple, nous avons ici la création d'un objet représentant un module
|
|
|
+d'analyse syntaxique XML. Le module est ensuite chargé dans l'objet. Puis un
|
|
|
+autre couple d'objet et module est chargé, cette fois-ci pour une \inltype{i_capability}
|
|
|
+de type \inltype{xml_reader}.
|
|
|
+
|
|
|
+% TODO: décrire module_need en détail et comment on peut vouloir la patcher pour
|
|
|
+% prendre en compte la sandbox.
|
|
|
+
|
|
|
+% TODO: parler de libvlc et vlc_object
|
|
|
++ parler des variables VLC
|
|
|
+
|
|
|
+
|
|
|
+\begin{code}{c}{API de requête de module}
|
|
|
+module_t *vlc_module_load(vlc_object_t *obj, const char *capability,
|
|
|
+ const char *name, bool strict,
|
|
|
+ vlc_activate_t probe, ...);
|
|
|
+
|
|
|
+module_t *module_need(vlc_object_t *obj, const char *cap, const char *name,
|
|
|
+ bool strict)
|
|
|
+\end{code}
|
|
|
+
|
|
|
+Les détails de ces fonctions sont décrits ici car il s'agit de l'interface
|
|
|
+exposée par VLC pour charger un nouveau module. C'est donc un point d'entrée
|
|
|
+potentiel pour l'injection des abstractions de la sandbox.
|