{"id":1611,"date":"2019-03-16T20:55:01","date_gmt":"2019-03-16T20:55:01","guid":{"rendered":"http:\/\/demensdeum.com\/blog\/?p=1611"},"modified":"2024-12-16T22:32:40","modified_gmt":"2024-12-16T19:32:40","slug":"%d1%81-application-plugins","status":"publish","type":"post","link":"https:\/\/demensdeum.com\/blog\/de\/2019\/03\/16\/%d1%81-application-plugins\/","title":{"rendered":"\u0421++ Application Plugins"},"content":{"rendered":"<p><span class=\"tlid-translation translation\" lang=\"en\"><span class=\"\" title=\"\">In this post I will describe an example of adding functionality to a C ++ application using plugins.<\/span> <span class=\"\" title=\"\">The practical part of the implementation for Linux is described; the theory can be found at the links at the end of the article.<\/span><\/span><\/p>\r\n<p><!-- \/wp:post-content --><\/p>\r\n<p><!-- wp:paragraph --><\/p>\r\n<p><!-- \/wp:paragraph --><\/p>\r\n<p><!-- wp:image {\"id\":1615,\"linkDestination\":\"custom\"} --><\/p>\r\n<figure class=\"wp-block-image\"><a href=\"https:\/\/twitter.com\/iamdevloper\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"617\" class=\"wp-image-1615\" src=\"https:\/\/demensdeum.com\/blog\/wp-content\/uploads\/2019\/03\/iamdev-1024x617.png\" alt=\"\" srcset=\"https:\/\/demensdeum.com\/blog\/wp-content\/uploads\/2019\/03\/iamdev-1024x617.png 1024w, https:\/\/demensdeum.com\/blog\/wp-content\/uploads\/2019\/03\/iamdev-300x181.png 300w, https:\/\/demensdeum.com\/blog\/wp-content\/uploads\/2019\/03\/iamdev-768x462.png 768w, https:\/\/demensdeum.com\/blog\/wp-content\/uploads\/2019\/03\/iamdev.png 1440w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a>\r\n<figcaption>Composition over inheritance!<\/figcaption>\r\n<\/figure>\r\n<p><!-- \/wp:image --><\/p>\r\n<p><!-- wp:paragraph --><\/p>\r\n<p><span class=\"tlid-translation translation\" lang=\"en\"><span class=\"\" title=\"\">To begin with, we will write a plugin &#8211; a function that we will call:<\/span><\/span><\/p>\r\n<p><!-- \/wp:paragraph --><\/p>\r\n<p><!-- HTML generated using hilite.me --><\/p>\r\n<div style=\"background: #ffffff; overflow: auto; width: auto; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;\">\r\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #557799;\">#include \"iostream\"<\/span>\r\n\r\n<span style=\"color: #008800; font-weight: bold;\">using<\/span> <span style=\"color: #008800; font-weight: bold;\">namespace<\/span> std;\r\n\r\n<span style=\"color: #008800; font-weight: bold;\">extern<\/span> <span style=\"background-color: #fff0f0;\">\"C\"<\/span> <span style=\"color: #333399; font-weight: bold;\">void<\/span> extensionEntryPoint() {\r\n\tcout <span style=\"color: #333333;\">&lt;&lt;<\/span> <span style=\"background-color: #fff0f0;\">\"Extension entry point called\"<\/span> <span style=\"color: #333333;\">&lt;&lt;<\/span> endl;\r\n};\r\n<\/pre>\r\n<\/div>\r\n<p><!-- wp:paragraph --><\/p>\r\n<p><span class=\"tlid-translation translation\" lang=\"en\"><span class=\"\" title=\"\">Next, we will build the plugin as a dynamic library &#8220;extension.so&#8221;, which we will connect in the future:<\/span><\/span><br \/><strong>clang++ -shared -fPIC extension.cpp -o extension.so<\/strong><\/p>\r\n<p><!-- \/wp:paragraph --><\/p>\r\n<p><!-- wp:paragraph --><\/p>\r\n<p>Next w<span class=\"tlid-translation translation\" lang=\"en\"><span class=\"\" title=\"\">e write the main application that will load the file &#8220;extension.so&#8221;, look for a pointer to the function &#8220;extensionEntryPoint&#8221; there, and call it, typing errors if necessary<\/span><\/span>:<\/p>\r\n<p><!-- \/wp:paragraph --><\/p>\r\n<p><!-- HTML generated using hilite.me --><\/p>\r\n<div style=\"background: #ffffff; overflow: auto; width: auto; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;\">\r\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #557799;\">#include \"iostream\"<\/span>\r\n<span style=\"color: #557799;\">#include \"dlfcn.h\"<\/span>\r\n\r\n<span style=\"color: #008800; font-weight: bold;\">using<\/span> <span style=\"color: #008800; font-weight: bold;\">namespace<\/span> std;\r\n\r\n<span style=\"color: #008800; font-weight: bold;\">typedef<\/span> <span style=\"color: #0066bb; font-weight: bold;\">void<\/span> (<span style=\"color: #333333;\">*<\/span>VoidFunctionPointer)();\t\r\n\r\n<span style=\"color: #333399; font-weight: bold;\">int<\/span> <span style=\"color: #0066bb; font-weight: bold;\">main<\/span> (<span style=\"color: #333399; font-weight: bold;\">int<\/span> argc, <span style=\"color: #333399; font-weight: bold;\">char<\/span> <span style=\"color: #333333;\">*<\/span>argv[]) {\r\n\r\n\tcout <span style=\"color: #333333;\">&lt;&lt;<\/span> <span style=\"background-color: #fff0f0;\">\"C++ Plugins Example\"<\/span> <span style=\"color: #333333;\">&lt;&lt;<\/span> endl;\r\n\r\n\t<span style=\"color: #008800; font-weight: bold;\">auto<\/span> extensionHandle <span style=\"color: #333333;\">=<\/span> dlopen(<span style=\"background-color: #fff0f0;\">\".\/extension.so\"<\/span>, RTLD_LAZY);\r\n\t<span style=\"color: #008800; font-weight: bold;\">if<\/span> (<span style=\"color: #333333;\">!<\/span>extensionHandle) {\r\n\t\tstring errorString <span style=\"color: #333333;\">=<\/span> dlerror();\r\n\t\t<span style=\"color: #008800; font-weight: bold;\">throw<\/span> runtime_error(errorString);\r\n\t}\r\n\r\n\t<span style=\"color: #008800; font-weight: bold;\">auto<\/span> functionPointer <span style=\"color: #333333;\">=<\/span> VoidFunctionPointer();\r\n\tfunctionPointer <span style=\"color: #333333;\">=<\/span> (VoidFunctionPointer) dlsym(extensionHandle, <span style=\"background-color: #fff0f0;\">\"extensionEntryPoint\"<\/span>);\r\n\t<span style=\"color: #008800; font-weight: bold;\">auto<\/span> dlsymError <span style=\"color: #333333;\">=<\/span> dlerror();\r\n \t<span style=\"color: #008800; font-weight: bold;\">if<\/span> (dlsymError) {\r\n\t\tstring errorString <span style=\"color: #333333;\">=<\/span> dlerror();\r\n\t\t<span style=\"color: #008800; font-weight: bold;\">throw<\/span> runtime_error(errorString);\r\n \t}\r\n\r\n\tfunctionPointer();\r\n\r\n\texit(<span style=\"color: #0000dd; font-weight: bold;\">0<\/span>);\r\n} \r\n<\/pre>\r\n<\/div>\r\n<p><!-- wp:paragraph --><\/p>\r\n<p><span class=\"tlid-translation translation\" lang=\"en\"><span title=\"\">The dlopen function returns a handler for working with a dynamic library;<\/span> <span class=\"\" title=\"\">dlsym function returns a pointer to the required function by string;<\/span> <span class=\"\" title=\"\">dlerror contains a pointer to the string with the error text, if any.<\/span><\/span><\/p>\r\n<p><!-- \/wp:paragraph --><\/p>\r\n<p><!-- wp:paragraph --><\/p>\r\n<p><span class=\"tlid-translation translation\" lang=\"en\"><span class=\"\" title=\"\">Next, build the main application, copy the file of the dynamic library in the folder with it and run.<\/span> <span class=\"\" title=\"\">The output should be the <strong>&#8220;Extension entry point called&#8221;<\/strong><\/span><\/span><strong><br \/><\/strong><\/p>\r\n<p><!-- \/wp:paragraph --><\/p>\r\n<p><!-- wp:paragraph --><\/p>\r\n<div class=\"text-wrap tlid-copy-target\">\r\n<div class=\"result-shield-container tlid-copy-target\" tabindex=\"0\"><span class=\"tlid-translation translation\" lang=\"en\"><span class=\"\" title=\"\">Difficult moments include the lack of a single standard for working with dynamic libraries, because of this there is a need to export the function to a relatively global scope with <strong>extern C<\/strong>;<\/span> <span title=\"\">the difference in working with different operating systems associated with this subtlety of work;<\/span> <span title=\"\">the lack of a C ++ interface to implement OOP approach to working with dynamic libraries, however, there are open-source wrappers, for example <a href=\"https:\/\/github.com\/m-renaud\/libdlibxx\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"m-renaud\/libdlibxx (opens in a new tab)\">m-renaud\/libdlibxx<\/a><br \/><\/span><\/span><\/div>\r\n<\/div>\r\n<h2>Example Source Code<\/h2>\r\n<p><!-- \/wp:paragraph --><\/p>\r\n<p><!-- wp:paragraph --><\/p>\r\n<p><a href=\"https:\/\/gitlab.com\/demensdeum\/cpppluginsexample\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\">https:\/\/gitlab.com\/demensdeum\/cpppluginsexample<\/a><\/p>\r\n<p><!-- \/wp:paragraph --><\/p>\r\n<p><!-- wp:heading --><\/p>\r\n<h2>Documents<\/h2>\r\n<p><!-- \/wp:heading --><\/p>\r\n<p><!-- wp:paragraph --><\/p>\r\n<p><a href=\"http:\/\/man7.org\/linux\/man-pages\/man3\/dlopen.3.html\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\">http:\/\/man7.org\/linux\/man-pages\/man3\/dlopen.3.htm<\/a><br \/><a href=\"https:\/\/gist.github.com\/tailriver\/30bf0c943325330b7b6a\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"https:\/\/gist.github.com\/tailriver\/30bf0c943325330b7b6a (opens in a new tab)\">https:\/\/gist.github.com\/tailriver\/30bf0c943325330b7b6a<\/a><br \/><a href=\"https:\/\/stackoverflow.com\/questions\/840501\/how-do-function-pointers-in-c-work\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"https:\/\/stackoverflow.com\/questions\/840501\/how-do-function-pointers-in-c-work (opens in a new tab)\">https:\/\/stackoverflow.com\/questions\/840501\/how-do-function-pointers-in-c-work<\/a><\/p>\r\n<p><!-- \/wp:paragraph --><\/p>","protected":false},"excerpt":{"rendered":"<p>In this post I will describe an example of adding functionality to a C ++ application using plugins. The practical part of the implementation for Linux is described; the theory can be found at the links at the end of the article. Composition over inheritance! To begin with, we will write a plugin &#8211; a<a class=\"more-link\" href=\"https:\/\/demensdeum.com\/blog\/de\/2019\/03\/16\/%d1%81-application-plugins\/\">Continue reading <span class=\"screen-reader-text\">&#8220;\u0421++ Application Plugins&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[61,52],"tags":[],"class_list":["post-1611","post","type-post","status-publish","format-standard","hentry","category-techie","category-tutorials","entry"],"translation":{"provider":"WPGlobus","version":"3.0.2","language":"de","enabled_languages":["en","ru","zh","de","fr","ja","pt"],"languages":{"en":{"title":true,"content":true,"excerpt":false},"ru":{"title":true,"content":true,"excerpt":false},"zh":{"title":false,"content":false,"excerpt":false},"de":{"title":false,"content":false,"excerpt":false},"fr":{"title":false,"content":false,"excerpt":false},"ja":{"title":false,"content":false,"excerpt":false},"pt":{"title":false,"content":false,"excerpt":false}}},"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/demensdeum.com\/blog\/de\/wp-json\/wp\/v2\/posts\/1611","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/demensdeum.com\/blog\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/demensdeum.com\/blog\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/de\/wp-json\/wp\/v2\/comments?post=1611"}],"version-history":[{"count":26,"href":"https:\/\/demensdeum.com\/blog\/de\/wp-json\/wp\/v2\/posts\/1611\/revisions"}],"predecessor-version":[{"id":1691,"href":"https:\/\/demensdeum.com\/blog\/de\/wp-json\/wp\/v2\/posts\/1611\/revisions\/1691"}],"wp:attachment":[{"href":"https:\/\/demensdeum.com\/blog\/de\/wp-json\/wp\/v2\/media?parent=1611"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/de\/wp-json\/wp\/v2\/categories?post=1611"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/de\/wp-json\/wp\/v2\/tags?post=1611"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}