From 7a458c5cbe1e85280614b26fa1270034b06933f1 Mon Sep 17 00:00:00 2001 From: peri4 Date: Sat, 23 Apr 2022 00:44:52 +0300 Subject: [PATCH] doc ru --- libs/main/system/pilibrary.cpp | 39 ++++++++-- libs/main/system/piplugin.cpp | 135 +++++++++++++++++++++++++++------ libs/main/system/piplugin.h | 91 ++++++++++++++-------- 3 files changed, 204 insertions(+), 61 deletions(-) diff --git a/libs/main/system/pilibrary.cpp b/libs/main/system/pilibrary.cpp index b02c52c2..edf60f81 100644 --- a/libs/main/system/pilibrary.cpp +++ b/libs/main/system/pilibrary.cpp @@ -44,12 +44,13 @@ //! to use it with \b new creation. //! //! Main method of %PILibrary is \a resolve(const char *), which returns -//! "void*" pointer to requested method. One should test it +//! \c void* pointer to requested method. One should test it //! to \c nullptr and convert it in pointer to the required method. //! -//! In case of C++ libraries it`s very important to use C-linkage +//! In case of C++ libraries it`s very important to use [C-linkage](https://en.cppreference.com/w/cpp/language/language_linkage) //! of exported methods! You may also need to mark methods for -//! export, e.g. \с __declspec(dllexport) +//! export, e.g. \c __declspec(dllexport). You can include \c +//! and use \a PIP_PLUGIN_EXPORT to mark exports with PIP. //! //! \~russian //! %PILibrary позволяет динамически загружать стороннюю библиотеку @@ -58,12 +59,13 @@ //! рекомендуется создавать её с помощью \b new. //! //! Основной метод %PILibrary - это \a resolve(const char *), который возвращает -//! "void*" указатель на запрошенный метод. Необходимо проверить его +//! \c void* указатель на запрошенный метод. Необходимо проверить его //! на \c nullptr и преобразовать в указатель на нужный метод. //! -//! В случае C++ библиотеки очень важно использовать C-linkage +//! В случае C++ библиотеки очень важно использовать [C-linkage](https://en.cppreference.com/w/cpp/language/language_linkage) //! для экспортируемых методов! Также может понадобиться пометить -//! методы на экспорт, например, \с __declspec(dllexport) +//! методы на экспорт, например, \c __declspec(dllexport). Можно включить \c +//! и использовать \a PIP_PLUGIN_EXPORT, чтобы пометить экспорт с помощью PIP. //! //! \~\code //! extern "C" { @@ -175,6 +177,31 @@ bool PILibrary::isLoaded() const { } +//! \~\details +//! \~english +//! Returns exported method with name "symbol" from +//! loaded library. Method have to use [C-linkage](https://en.cppreference.com/w/cpp/language/language_linkage) and +//! marked to export, according to compiler specification.\n +//! C-linkage doesn`t provide information about return type +//! and arguments, so you should manually convert obtained +//! pointer to required method format before call. +//! +//! \~russian +//! Возвращает экспортированный метод с именем "symbol" +//! из загруженной библиотеки. Метод должен иметь [C-linkage](https://en.cppreference.com/w/cpp/language/language_linkage) +//! и помечен для экспорта, согласно спецификации компилятора.\n +//! C-linkage не предоставляет информации о возвращаемом типе +//! и аргументах, поэтому необходимо вручную преобразовать +//! полученный указатель к формату требуемого метода перед вызовом. +//! +//! \~\return +//! \~english +//! \b void* pointer to method or\n +//! \b nullptr if method doesn`t exists or library not loaded +//! +//! \~russian +//! \b void* указатель на метод или\n +//! \b nullptr если метод не существует или библиотека не загружена void * PILibrary::resolve(const char * symbol) { if (!isLoaded()) return 0; void * ret; diff --git a/libs/main/system/piplugin.cpp b/libs/main/system/piplugin.cpp index 444049c4..e3fdf52b 100644 --- a/libs/main/system/piplugin.cpp +++ b/libs/main/system/piplugin.cpp @@ -32,13 +32,24 @@ //! \~english Plugin loader //! \~russian Загрузчик плагина //! -//! \section PIPluginLoader_sec0 Synopsis -//! This class provides several macro to define plugin and %PIPluginLoader - class +//! \~\details +//! \~english \section PIPluginLoader_sec0 Synopsis +//! \~russian \section PIPluginLoader_sec0 Краткий обзор +//! +//! \~english +//! This file provides several macro to define plugin and %PIPluginLoader - class //! to load and check plugin. //! -//! \section PIPluginLoader_sec1 Plugin side +//! \~russian +//! Этот файл предоставляет несколько макросов для объявления плагина и +//! %PIPluginLoader - класс для его загрузки и проверки. +//! +//! +//! \~english \section PIPluginLoader_sec1 Plugin side +//! \~russian \section PIPluginLoader_sec1 Сторона плагина +//! \~english //! Plugin is a shared library that can be loaded in run-time. -//! This is only PIP_PLUGIN macro necessary to define plugin. +//! This is only \a PIP_PLUGIN macro necessary to define plugin. //! If you want to set and check some version, use macro //! \a PIP_PLUGIN_SET_USER_VERSION(version). Also you can //! define a function to merge static sections between application @@ -46,38 +57,84 @@ //! merge, you should set pointers to that sections with macro //! \a PIP_PLUGIN_ADD_STATIC_SECTION(type, ptr). //! -//! \section PIPluginLoader_sec2 Application side +//! \~russian +//! Плагин - это разделяемая библиотека, которая может быть +//! загружена динамически. Необходимым является только макрос \a PIP_PLUGIN. +//! Можно установить версию для дополнительной проверки с помощью +//! макроса \a PIP_PLUGIN_SET_USER_VERSION(version). Также +//! можно объявить метод для слияния статических секций между +//! приложением и плагином с помощью макроса \a PIP_PLUGIN_STATIC_SECTION_MERGE. +//! Перед слиянием необходимо установить указатели для секций с +//! помощью макроса \a PIP_PLUGIN_ADD_STATIC_SECTION(type, ptr). +//! +//! +//! \~english \section PIPluginLoader_sec2 Application side +//! \~russian \section PIPluginLoader_sec2 Сторона приложения +//! \~english //! Application should use class \a PIPluginLoader to load //! plugin. Main function is \a load(PIString name). //! "name" is base name of library, %PIPluginLoader //! try to use sevaral names, \, lib\ and -//! "dll", "so" and "dylib" extensions, depends on system. +//! "dll", "so" and "dylib" extensions, depends on system.\n //! For example: -//! \code +//! +//! \~russian +//! Приложение должно использовать класс \a PIPluginLoader +//! для загрузки плагина. Основной метод - это \a load(PIString name). +//! "name" является базовым именем для поиска библиотеки. +//! %PIPluginLoader попробует несколько имен, \, lib\ и +//! расширения "dll", "so" и "dylib", в зависимости от системы.\n +//! Например: +//! +//! \~\code //! PIPluginLoader l; //! l.load("foo"); //! \endcode +//! +//! \~english //! On Windows, try to open "foo", "libfoo", "foo.dll" and -//! "libfoo.dll". +//! "libfoo.dll".\n //! If you using user version check, you should set it //! with macro \a PIP_PLUGIN_SET_USER_VERSION(version). //! When plugin is successfully loaded and checked, //! you can load your custom symbols with function //! \a resolve(name), similar to PILibrary. -//! \note You should use PIP_PLUGIN_EXPORT and "export "C"" +//! \note You should use \a PIP_PLUGIN_EXPORT and [C-linkage](https://en.cppreference.com/w/cpp/language/language_linkage) //! with functions you want to use with \a resolve(name)! //! -//! \section PIPluginLoader_sec3 Static sections +//! \~russian +//! На Windows будут опробованы "foo", "libfoo", "foo.dll" и +//! "libfoo.dll".\n +//! Если нужна проверка пользовательской версии, установите +//! ей с помощью макроса \a PIP_PLUGIN_SET_USER_VERSION(version). +//! Когда плагин будет успешно загружен и проверен, можно будет +//! получать из него свои методы с помощью \a resolve(name), +//! аналогично PILibrary. +//! \note Необходимо использовать \a PIP_PLUGIN_EXPORT и [C-linkage](https://en.cppreference.com/w/cpp/language/language_linkage) +//! для методов, получаемых через \a resolve(name)! +//! +//! +//! \~english \section PIPluginLoader_sec3 Static sections +//! \~russian \section PIPluginLoader_sec3 Статические секции +//! \~english //! Macro \a PIP_PLUGIN_STATIC_SECTION_MERGE defines function //! with arguments (int type, void * from, void * to), so you //! can leave this macro as declaration or define its body next: -//! \code +//! +//! \~russian +//! Макрос \a PIP_PLUGIN_STATIC_SECTION_MERGE объявляет метод +//! с аргументами (int type, void * from, void * to), поэтому +//! можно оставить его как объявление, или реализовать тут же: +//! +//! \~\code //! PIP_PLUGIN_STATIC_SECTION_MERGE() { //! switch (type) { //! ... //! } //! } //! \endcode +//! +//! \~english //! \note If you using singletones, remember that cpp-defined //! singletones in shared libraries are single for whole application, //! including plugins! But if you use h-defined singletones or @@ -87,14 +144,31 @@ //! Anyway, if this is macro \a PIP_PLUGIN_STATIC_SECTION_MERGE, it //! called once while loading plugin with "from" - plugin side //! and "to" - application side, and second (optionally) on method -//! \a mergeStatic() with "from" - application side and "to" - plugin side. +//! \a mergeStatic() with "from" - application side and "to" - plugin side.\n //! First direction allow you to copy all defined static content from plugin //! to application, and second - after loading all plugins (for example) -//! to copy static content from application (and all plugins) to plugin. +//! to copy static content from application (and all other plugins) to plugin. //! -//! \section PIPluginLoader_sec4 Examples -//! Simple plugin: -//! \code +//! \~russian +//! \note При использовании синглтонов надо помнить, что реализованные +//! в cpp синглтоны в разделяемых библиотеках едины для всего приложения, +//! включая плагины! Однако реализованные в h-файлах синглтоны, либо +//! из статических библиотек, не являются реальными одиночками, +//! и для каждого плагина и приложения будет свой объект. В этом случае +//! можно провести слияние статических секций. +//! +//! В любом случае, если используется макрос \a PIP_PLUGIN_STATIC_SECTION_MERGE, +//! то он вызывается первый раз во время загрузки плагина с "from" - областью плагина, +//! "to" - областью приложения, и второй раз (необязательно) при вызове +//! \a mergeStatic() с "from" - областью приложения и "to" - областью плагина.\n +//! Первый вызов позволяет скопировать статические секции из плагина в приложение, +//! второй - из приложения (и всех остальных плагинов) в плагин. +//! +//! \~english \section PIPluginLoader_sec4 Examples +//! \~russian \section PIPluginLoader_sec4 Примеры +//! \~english Simple plugin: +//! \~russian Простой плагин: +//! \~\code //! #include //! //! PIP_PLUGIN @@ -106,8 +180,9 @@ //! } //! \endcode //! -//! Application: -//! \code +//! \~english Application: +//! \~russian Приложение: +//! \~\code //! #include //! int main() { //! PIPluginLoader pl; @@ -121,8 +196,9 @@ //! } //! \endcode //! -//! Complex plugin: -//! \code +//! \~english Complex plugin: +//! \~russian Сложный плагин: +//! \~\code //! #include //! //! PIStringList global_list; @@ -142,8 +218,9 @@ //! } //! \endcode //! -//! Application: -//! \code +//! \~english Application: +//! \~russian Приложение: +//! \~\code //! #include //! //! PIStringList global_list; @@ -254,6 +331,13 @@ PIPluginLoader::~PIPluginLoader() { } +//! \~\details +//! \~english +//! Loader try prefix "lib" and suffix ".dll", +//! ".so" or ".dylib", depends on platform. +//! \~russian +//! Загрузчик пробует приставку "lib" и окончания +//! ".dll", ".so" или ".dylib", в зависимости от системы bool PIPluginLoader::load(const PIString & name) { unload(); PIPluginInfo * ai = PIPluginInfoStorage::instance()->applicationInfo(); @@ -356,6 +440,13 @@ void * PIPluginLoader::resolve(const char * name) { } +//! \~\details +//! \~english +//! Call PIP_PLUGIN_STATIC_SECTION_MERGE function +//! on every common type, with "from" - application scope, +//! "to" - plugin scope +//! \~russian +//! void PIPluginLoader::mergeStatic() { if (!loaded || !func_static_merge) return; PIPluginInfo * ai = PIPluginInfoStorage::instance()->applicationInfo(); diff --git a/libs/main/system/piplugin.h b/libs/main/system/piplugin.h index fcf2794e..e3eb8ee4 100644 --- a/libs/main/system/piplugin.h +++ b/libs/main/system/piplugin.h @@ -34,30 +34,44 @@ #ifdef DOXYGEN -//! Declare plugin export functions, should be used before other PIP_PLUGIN_* macros -//! \relatedalso PIPluginLoader +//! \~english Declare plugin, should be used before other PIP_PLUGIN_* macros +//! \~russian Объявляет плагин, должен быть использован перед любыми другими PIP_PLUGIN_* макросами +//! \~\relatesalso PIPluginLoader #define PIP_PLUGIN -//! Set user version to check it while loading -//! \relatedalso PIPluginLoader +//! \~english Set user version to check it while loading, "version" is quoted string +//! \~russian Устанавливает пользовательскую версию для проверки во время загрузки, "version" - строка в кавычках +//! \~\relatesalso PIPluginLoader #define PIP_PLUGIN_SET_USER_VERSION(version) -//! Add pointer to future merge with plugin. Type is integer -//! \relatedalso PIPluginLoader +//! \~english Add pointer to future merge with plugin. Type is integer +//! \~russian Добавляет указатель для будущего слияния. Тип - целое число +//! \~\relatesalso PIPluginLoader #define PIP_PLUGIN_ADD_STATIC_SECTION(type, ptr) -//! Declare function to merge static sections. This is functions -//! with 3 arguments: (int type, void * from, void * to). +//! \~english Declare function to merge static sections +//! \~russian Объявляет метод для слияния статических секций +//! \~\details +//! \~english +//! This is functions with 3 arguments: (int type, void * from, void * to). //! This function invoked first while loading plugin with //! "from" - plugin scope, "to" - application scope, and second //! (optionally) on \a PIPluginLoader::mergeStatic() method with //! "from" - application scope, "to" - plugin scope. So with macro //! you can merge application and plugin static data. -//! \relatedalso PIPluginLoader +//! \~russian +//! Этот метод имеет 3 аргумента: (int type, void * from, void * to). +//! Он вызывается первый раз при загрузке плагина с "from" - областью плагина, +//! "to" - областью приложения, и второй раз (необязательно) при вызове +//! \a PIPluginLoader::mergeStatic() с "from" - областью приложения и +//! "to" - областью плагина. Таким образом, этот макрос позволяет провести +//! слияние статических данных приложения и плагина. +//! \~\relatesalso PIPluginLoader #define PIP_PLUGIN_STATIC_SECTION_MERGE -//! Mark method to export -//! \relatedalso PIPluginLoader +//! \~english Mark method to export +//! \~russian Пометить метод на экспорт +//! \~\relatesalso PIPluginLoader #define PIP_PLUGIN_EXPORT @@ -147,54 +161,65 @@ public: typedef int(*FunctionLoaderVersion)(); typedef void(*FunctionStaticMerge)(int, void *, void *); - //! Possible load plugin error + //! \~english Possible load plugin error + //! \~russian Возможные ошибки загрузки плагина enum Error { - Unknown /** No \a load call yet */ , - NoError /** No error */ , - LibraryLoadError /** System can`t load library */ , - MissingSymbols /** Can`t find necessary symbols */ , - InvalidLoaderVersion /** Integer version mismatch */ , - InvalidUserVersion /** User version mismatch */ , + Unknown /** \~english No \a load() call yet \~russian Не было вызова \a load() */ , + NoError /** \~english No error \~russian Нет ошибки */ , + LibraryLoadError /** \~english System can`t load library \~russian Система не смогла загрузить библиотеку */ , + MissingSymbols /** \~english Can`t find necessary symbols \~russian Нет необходимых методов */ , + InvalidLoaderVersion /** \~english Internal version mismatch \~russian Неверная внутренняя версия */ , + InvalidUserVersion /** \~english User version mismatch \~russian Неверная пользовательская версия */ , }; - //! Contruscts loader with filename "name" + //! \~english Contruct loader with base filename "name" and call \a load() if "name" not empty + //! \~russian Создает загрузчик с базовым именем файла "name" и вызывает \a load() если "name" не пустое PIPluginLoader(const PIString & name = PIString()); - //! Destructor + //! \~english Destructor, unload library + //! \~russian Деструктор, выгружает библиотеку ~PIPluginLoader(); - //! Load plugin with base filename "name". Loader try prefix "lib" - //! and suffix ".dll", ".so" or ".dylib", depends on platform + //! \~english Load plugin with base filename "name" + //! \~russian Загружает плагин с базовым именем "name" bool load(const PIString & name); - //! Unload plugin and free library + //! \~english Unload plugin and free library + //! \~russian Выгружает плагин и освобождает библиотеку void unload(); - //! Returns if plugin is successfully loaded + //! \~english Returns if plugin is successfully loaded + //! \~russian Возвращает успешно ли загружен плагин bool isLoaded() const; - //! Returns error of last \a load() call + //! \~english Returns error of last \a load() call + //! \~russian Возвращает ошибку последнего вызова \a load() Error lastError() const; - //! Returns error message of last \a load() call + //! \~english Returns error message of last \a load() call + //! \~russian Возвращает сообщение об ошибке последнего вызова \a load() PIString lastErrorText() const; - //! Set if %PIPluginLoader should print load messages, \b true by default + //! \~english Set if %PIPluginLoader should print load messages, \b true by default + //! \~russian Устанавливает должен ли %PIPluginLoader выводить сообщения, \b true по умолчанию void setMessages(bool yes); - //! Returns if %PIPluginLoader should print load messages, \b true by default + //! \~english Returns if %PIPluginLoader should print load messages, \b true by default + //! \~russian Возвращает должен ли %PIPluginLoader выводить сообщения, \b true по умолчанию bool isMessages() const; - //! Returns loaded plugin library path + //! \~english Returns loaded plugin library path + //! \~russian Возвращает путь к загруженной библиотеке PIString libPath(); - //! Resolve symbol "name" from plugin library + //! \~english Obtain exported library method with name "symbol" + //! \~russian Получает экспортированный метод библиотеки с именем "symbol" + //! \~\sa PILibrary::resolve() void * resolve(const char * name); - //! Invoke plugin PIP_PLUGIN_STATIC_SECTION_MERGE function - //! on every common type, with "from" - application scope, - //! "to" - plugin scope + //! \~english Invoke plugin \a PIP_PLUGIN_STATIC_SECTION_MERGE + //! \~russian Вызывает у плагина \a PIP_PLUGIN_STATIC_SECTION_MERGE void mergeStatic(); static PIStringList pluginsDirectories(const PIString & name);