{"id":272,"date":"2011-04-21T13:30:58","date_gmt":"2011-04-21T13:30:58","guid":{"rendered":"https:\/\/blogs.mathworks.com\/loren\/2011\/04\/21\/deploying-multiple-c-shared-libraries\/"},"modified":"2011-03-23T13:31:38","modified_gmt":"2011-03-23T13:31:38","slug":"deploying-multiple-c-shared-libraries","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/loren\/2011\/04\/21\/deploying-multiple-c-shared-libraries\/","title":{"rendered":"Deploying Multiple C++ Shared Libraries"},"content":{"rendered":"<div xmlns:mwsh=\"https:\/\/www.mathworks.com\/namespace\/mcode\/v1\/syntaxhighlight.dtd\" class=\"content\">\r\n   <introduction>\r\n      <p>Guest blogger <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/4660\">Peter Webb<\/a> returns with another in an <a href=\"https:\/\/blogs.mathworks.com\/loren\/category\/deployment\/\">occasional series<\/a> of postings about application deployment.\r\n      <\/p>\r\n   <\/introduction>\r\n   <h3>Contents<\/h3>\r\n   <div>\r\n      <ul>\r\n         <li><a href=\"#2\">Building the Shared Libraries<\/a><\/li>\r\n         <li><a href=\"#3\">Using Two Libraries<\/a><\/li>\r\n         <li><a href=\"#4\">Building and Running the Application<\/a><\/li>\r\n      <\/ul>\r\n   <\/div>\r\n   <p>Grouping related functions into separate shared libraries is very common, as it promotes good software design and maintainability\r\n      via <a href=\"http:\/\/en.wikipedia.org\/wiki\/Separation_of_concerns\">separation of concerns<\/a>. A single application almost always calls functions from multiple shared libraries.\r\n   <\/p>\r\n   <p>To show you how to build applications that use multiple <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2011a\/toolbox\/compiler\/br5w5e9-1.html\">MATLAB Compiler<\/a>-generated shared libraries, I've written an example program that computes and displays the <a href=\"http:\/\/en.wikipedia.org\/wiki\/Mandelbrot_set\">Mandelbrot set<\/a>, a shape with a fractal boundary.\r\n   <\/p>\r\n   <p>The application consists of three parts:<\/p>\r\n   <div>\r\n      <ul>\r\n         <li>Two shared libraries, each generated by MATLAB Compiler.<\/li>\r\n         <li>A main program that interprets command line arguments and calls functions in the shared libraries.<\/li>\r\n      <\/ul>\r\n   <\/div>\r\n   <p>Each of the MATLAB Compiler-generated shared libraries provides a specific kind of functionality: the <tt>libmandelbrot<\/tt> library performs mathematical calculations, while <tt>libimage<\/tt> displays images.\r\n   <\/p>\r\n   <h3>Building the Shared Libraries<a name=\"2\"><\/a><\/h3>\r\n   <p><a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/29445-deploying-multiple-shared-libraries\">Download the code<\/a> for this example from MATLAB Central, unpack the ZIP files in a new folder, and then use the <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2011a\/toolbox\/compiler\/f0-985134.html\">mcc command<\/a> to create the shared libraries:\r\n   <\/p><pre>mcc -Nv -W cpplib:libmandelbrot -T link:lib mandelbrot.m\r\nmcc -Nv -W cpplib:libimage -T link:lib showimage.m<\/pre><p>Note the use of <tt>-W cpplib<\/tt>, which creates C++ shared libraries. Functions exported from C++ shared libraries are easier to use than those exported from\r\n      C shared libraries.\r\n   <\/p>\r\n   <h3>Using Two Libraries<a name=\"3\"><\/a><\/h3>\r\n   <p>The main program, in <tt>fractal.cpp<\/tt>, <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2011a\/toolbox\/compiler\/mclinitializeapplication.html\">initializes the application<\/a> as usual:\r\n   <\/p><pre> if (!mclInitializeApplication(NULL,0))\r\n {\r\n      std::cerr &lt;&lt; \"Could not initialize the application properly.\"\r\n                &lt;&lt; std::endl;\r\n  \treturn -1;\r\n }<\/pre><p>Then, it initializes each shared library in turn:<\/p><pre>  \/\/ Initialize the mandelbrot library\r\n  if( !libmandelbrotInitialize() )\r\n  {\r\n      std::cerr &lt;&lt; \"Could not initialize the mandelbrot library properly.\"\r\n                &lt;&lt; std::endl;\r\n      return -1;\r\n  }<\/pre><pre>  \/\/ Initialize the image library\r\n  if( !libimageInitialize() )\r\n  {\r\n      std::cerr &lt;&lt; \"Could not initialize the image library properly.\"\r\n                &lt;&lt; std::endl;\r\n      return -2;\r\n  }<\/pre><p>By testing the value returned from each library's initialization function, <tt>fractal<\/tt> provides accurate error messages should initialization fail.\r\n   <\/p>\r\n   <p>Each library exports a single function.<\/p>\r\n   <div>\r\n      <ul>\r\n         <li><tt>libmandelbrot<\/tt> exports <tt>fractal = mandelbrot(size, iterations)<\/tt><\/li>\r\n         <li><tt>libimage<\/tt> exports <tt>showimage(fractal)<\/tt><\/li>\r\n      <\/ul>\r\n   <\/div>\r\n   <p>The <tt>fractal<\/tt> main program calls <tt>mandelbrot<\/tt> to generate truecolor (24 bit) image data for the Mandelbrot set at a given size and resolution.\r\n   <\/p><pre>  mwArray fractal;\r\n  mandelbrot(1, fractal, width, limit);<\/pre><p><tt>mandelbrot<\/tt> returns the image data as an <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2011a\/toolbox\/compiler\/f0-98564.html\"><tt>mwArray<\/tt><\/a> object, which the main program then passes to <tt>showimage<\/tt>. This demonstrates that an <tt>mwArray<\/tt> created in one shared library can be processed in another; an <tt>mwArray<\/tt> is independent of the shared library that created it.\r\n   <\/p><pre> showimage(fractal);<\/pre><p><tt>showimage<\/tt> creates an image from the image data and displays the image in a figure window.\r\n   <\/p>\r\n   <h3>Building and Running the Application<a name=\"4\"><\/a><\/h3>\r\n   <p>Compile the main program and link it with the two shared libraries using <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2011a\/toolbox\/compiler\/mbuild.html\"><tt>mbuild<\/tt><\/a>. The <tt>mbuild<\/tt> command varies by platform:\r\n   <\/p>\r\n   <div>\r\n      <ul>\r\n         <li>Windows: <tt>mbuild -g -v fractal.cpp libmandelbrot.lib libimage.lib<\/tt><\/li>\r\n         <li>UNIX: <tt>mbuild -g -v fractal.cpp -L. -lmandelbrot -limage<\/tt><\/li>\r\n      <\/ul>\r\n   <\/div>\r\n   <p>Then, create a Mandelbrot set 500 pixels wide with an iteration limit of 100 by running the <tt>fractal<\/tt> program:\r\n   <\/p><pre>fractal 500 100<\/pre><p>Mandelbrot sets require a significant amout of computation. The example above takes about 45 seconds on a PC with a 2.5GHz\r\n      processor. A 2000-pixel wide set requires more than 15 minutes.\r\n   <\/p>\r\n   <p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/loren\/272\/cyanset.png\"> <\/p>\r\n   <p>Have you ever written an application that uses multiple Compiler-generated libraries? Did it work as you expected? Let me\r\n      know <a href=\"https:\/\/blogs.mathworks.com\/loren\/?p=272#respond\">here<\/a>.\r\n   <\/p><script language=\"JavaScript\">\r\n<!--\r\n\r\n    function grabCode_8062cd4ae7be464a808ccf2c126eac94() {\r\n        \/\/ Remember the title so we can use it in the new page\r\n        title = document.title;\r\n\r\n        \/\/ Break up these strings so that their presence\r\n        \/\/ in the Javascript doesn't mess up the search for\r\n        \/\/ the MATLAB code.\r\n        t1='8062cd4ae7be464a808ccf2c126eac94 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 8062cd4ae7be464a808ccf2c126eac94';\r\n    \r\n        b=document.getElementsByTagName('body')[0];\r\n        i1=b.innerHTML.indexOf(t1)+t1.length;\r\n        i2=b.innerHTML.indexOf(t2);\r\n \r\n        code_string = b.innerHTML.substring(i1, i2);\r\n        code_string = code_string.replace(\/REPLACE_WITH_DASH_DASH\/g,'--');\r\n\r\n        \/\/ Use \/x3C\/g instead of the less-than character to avoid errors \r\n        \/\/ in the XML parser.\r\n        \/\/ Use '\\x26#60;' instead of '<' so that the XML parser\r\n        \/\/ doesn't go ahead and substitute the less-than character. \r\n        code_string = code_string.replace(\/\\x3C\/g, '\\x26#60;');\r\n\r\n        author = 'Peter Webb';\r\n        copyright = 'Copyright 2011 The MathWorks, Inc.';\r\n\r\n        w = window.open();\r\n        d = w.document;\r\n        d.write('<pre>\\n');\r\n        d.write(code_string);\r\n\r\n        \/\/ Add author and copyright lines at the bottom if specified.\r\n        if ((author.length > 0) || (copyright.length > 0)) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (author.length > 0) {\r\n                d.writeln('% _' + author + '_');\r\n            }\r\n            if (copyright.length > 0) {\r\n                d.writeln('% _' + copyright + '_');\r\n            }\r\n        }\r\n\r\n        d.write('<\/pre>\\n');\r\n      \r\n      d.title = title + ' (MATLAB code)';\r\n      d.close();\r\n      }   \r\n      \r\n-->\r\n<\/script><p style=\"text-align: right; font-size: xx-small; font-weight:lighter;   font-style: italic; color: gray\"><br><a href=\"javascript:grabCode_8062cd4ae7be464a808ccf2c126eac94()\"><span style=\"font-size: x-small;        font-style: italic;\">Get \r\n            the MATLAB code \r\n            <noscript>(requires JavaScript)<\/noscript><\/span><\/a><br><br>\r\n      Published with MATLAB&reg; 7.11<br><\/p>\r\n<\/div>\r\n<!--\r\n8062cd4ae7be464a808ccf2c126eac94 ##### SOURCE BEGIN #####\r\n%% Deploying Multiple C++ Shared Libraries\r\n% Guest blogger \r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/4660 Peter Webb>\r\n% returns with another in an \r\n% <https:\/\/blogs.mathworks.com\/loren\/category\/deployment\/ occasional series>\r\n% of postings about application deployment. \r\n\r\n%% \r\n% Grouping related functions into separate shared libraries is very common,\r\n% as it promotes good software design and maintainability via \r\n% <http:\/\/en.wikipedia.org\/wiki\/Separation_of_concerns separation of\r\n% concerns>. A single application almost always calls functions from \r\n% multiple shared libraries. \r\n%\r\n% To show you how to build applications that use multiple \r\n% <https:\/\/www.mathworks.com\/help\/releases\/R2011a\/toolbox\/compiler\/br5w5e9-1.html \r\n% MATLAB Compiler>-generated shared libraries, I've written an example program\r\n% that computes and displays the \r\n% <http:\/\/en.wikipedia.org\/wiki\/Mandelbrot_set Mandelbrot set>, a shape\r\n% with a fractal boundary. \r\n%\r\n% The application consists of three parts:\r\n%\r\n% * Two shared libraries, each generated by MATLAB Compiler.\r\n% * A main program that interprets command line arguments and calls \r\n% functions in the shared libraries.\r\n%\r\n% Each of the MATLAB Compiler-generated shared libraries provides a\r\n% specific kind of functionality: the |libmandelbrot| library performs \r\n% mathematical calculations, while |libimage| displays images. \r\n% \r\n%% Building the Shared Libraries\r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/29445-deploying-multiple-shared-libraries \r\n% Download the code> for this example from MATLAB Central, unpack the ZIP\r\n% files in a new folder, and then use the \r\n% <https:\/\/www.mathworks.com\/help\/releases\/R2011a\/toolbox\/compiler\/f0-985134.html \r\n% mcc command> to create the shared libraries:\r\n%\r\n%  mcc -Nv -W cpplib:libmandelbrot -T link:lib mandelbrot.m\r\n%  mcc -Nv -W cpplib:libimage -T link:lib showimage.m\r\n%\r\n% Note the use of |-W cpplib|, which creates C++ shared libraries.\r\n% Functions exported from C++ shared libraries are easier to use than those\r\n% exported from C shared libraries.\r\n%\r\n%% Using Two Libraries\r\n% The main program, in |fractal.cpp|, \r\n% <https:\/\/www.mathworks.com\/help\/releases\/R2011a\/toolbox\/compiler\/mclinitializeapplication.html\r\n% initializes the application> as usual:\r\n%\r\n%   if (!mclInitializeApplication(NULL,0)) \r\n%   {\r\n%        std::cerr << \"Could not initialize the application properly.\"\r\n%                  << std::endl;\r\n%    \treturn -1;\r\n%   }\r\n%\r\n% Then, it initializes each shared library in turn:\r\n%\r\n%    \/\/ Initialize the mandelbrot library\r\n%    if( !libmandelbrotInitialize() )\r\n%    {\r\n%        std::cerr << \"Could not initialize the mandelbrot library properly.\"\r\n%                  << std::endl;\r\n%        return -1;\r\n%    }\r\n%\r\n%    \/\/ Initialize the image library\r\n%    if( !libimageInitialize() )\r\n%    {\r\n%        std::cerr << \"Could not initialize the image library properly.\"\r\n%                  << std::endl;\r\n%        return -2;\r\n%    }\r\n%\r\n% By testing the value returned from each library's initialization\r\n% function, |fractal| provides accurate error messages should\r\n% initialization fail.\r\n%\r\n% Each library exports a single function. \r\n%\r\n% * |libmandelbrot| exports |fractal = mandelbrot(size, iterations)|\r\n% * |libimage| exports |showimage(fractal)|\r\n%\r\n% The |fractal| main program calls |mandelbrot| to generate truecolor\r\n% (24 bit) image data for the Mandelbrot set at a given size and \r\n% resolution.\r\n%\r\n%    mwArray fractal;\r\n%    mandelbrot(1, fractal, width, limit);\r\n%\r\n% |mandelbrot| returns the image data as an \r\n% <https:\/\/www.mathworks.com\/help\/releases\/R2011a\/toolbox\/compiler\/f0-98564.html\r\n% |mwArray|> object, which the\r\n% main program then passes to |showimage|. This demonstrates that an\r\n% |mwArray| created in one shared library can be processed in another;\r\n% an |mwArray| is independent of the shared library that created it.\r\n%\r\n%   showimage(fractal);\r\n%\r\n% |showimage| creates an image from the image data and displays the image\r\n% in a figure window.\r\n%\r\n%% Building and Running the Application\r\n% Compile the main program and link it with the two shared libraries using\r\n% <https:\/\/www.mathworks.com\/help\/releases\/R2011a\/toolbox\/compiler\/mbuild.html \r\n% |mbuild|>. The |mbuild| command varies by platform:\r\n%\r\n% * Windows: |mbuild -g -v fractal.cpp libmandelbrot.lib libimage.lib|\r\n% * UNIX: |mbuild -g -v fractal.cpp -L. -lmandelbrot -limage|\r\n%\r\n% Then, create a Mandelbrot set 500 pixels wide with an iteration limit of\r\n% 100 by running the |fractal| program:\r\n%\r\n%  fractal 500 100\r\n% \r\n% Mandelbrot sets require a significant amout of computation. The example\r\n% above takes about 45 seconds on a PC with a 2.5GHz processor. \r\n% A 2000-pixel wide set requires more than 15 minutes.\r\n%\r\n% <<cyanset.png>>\r\n%\r\n% Have you ever written an application that uses multiple\r\n% Compiler-generated libraries? Did it work as you expected? Let me know\r\n% <https:\/\/blogs.mathworks.com\/loren\/?p=272#respond here>.\r\n##### SOURCE END ##### 8062cd4ae7be464a808ccf2c126eac94\r\n-->","protected":false},"excerpt":{"rendered":"<p>\r\n   \r\n      Guest blogger Peter Webb returns with another in an occasional series of postings about application deployment.\r\n      \r\n   \r\n   Contents\r\n   \r\n      \r\n   ... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/loren\/2011\/04\/21\/deploying-multiple-c-shared-libraries\/\">read more >><\/a><\/p>","protected":false},"author":39,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[24],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/272"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/users\/39"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/comments?post=272"}],"version-history":[{"count":0,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/272\/revisions"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/media?parent=272"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/categories?post=272"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/tags?post=272"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}