Deploying Multiple C++ Shared Libraries
Guest blogger Peter Webb returns with another in an occasional series of postings about application deployment.
Contents
Grouping related functions into separate shared libraries is very common, as it promotes good software design and maintainability via separation of concerns. A single application almost always calls functions from multiple shared libraries.
To show you how to build applications that use multiple MATLAB Compiler-generated shared libraries, I've written an example program that computes and displays the Mandelbrot set, a shape with a fractal boundary.
The application consists of three parts:
- Two shared libraries, each generated by MATLAB Compiler.
- A main program that interprets command line arguments and calls functions in the shared libraries.
Each of the MATLAB Compiler-generated shared libraries provides a specific kind of functionality: the libmandelbrot library performs mathematical calculations, while libimage displays images.
Building the Shared Libraries
Download the code for this example from MATLAB Central, unpack the ZIP files in a new folder, and then use the mcc command to create the shared libraries:
mcc -Nv -W cpplib:libmandelbrot -T link:lib mandelbrot.m mcc -Nv -W cpplib:libimage -T link:lib showimage.m
Note the use of -W cpplib, which creates C++ shared libraries. Functions exported from C++ shared libraries are easier to use than those exported from C shared libraries.
Using Two Libraries
The main program, in fractal.cpp, initializes the application as usual:
if (!mclInitializeApplication(NULL,0)) { std::cerr << "Could not initialize the application properly." << std::endl; return -1; }
Then, it initializes each shared library in turn:
// Initialize the mandelbrot library if( !libmandelbrotInitialize() ) { std::cerr << "Could not initialize the mandelbrot library properly." << std::endl; return -1; }
// Initialize the image library if( !libimageInitialize() ) { std::cerr << "Could not initialize the image library properly." << std::endl; return -2; }
By testing the value returned from each library's initialization function, fractal provides accurate error messages should initialization fail.
Each library exports a single function.
- libmandelbrot exports fractal = mandelbrot(size, iterations)
- libimage exports showimage(fractal)
The fractal main program calls mandelbrot to generate truecolor (24 bit) image data for the Mandelbrot set at a given size and resolution.
mwArray fractal; mandelbrot(1, fractal, width, limit);
mandelbrot returns the image data as an mwArray object, which the main program then passes to showimage. This demonstrates that an mwArray created in one shared library can be processed in another; an mwArray is independent of the shared library that created it.
showimage(fractal);
showimage creates an image from the image data and displays the image in a figure window.
Building and Running the Application
Compile the main program and link it with the two shared libraries using mbuild. The mbuild command varies by platform:
- Windows: mbuild -g -v fractal.cpp libmandelbrot.lib libimage.lib
- UNIX: mbuild -g -v fractal.cpp -L. -lmandelbrot -limage
Then, create a Mandelbrot set 500 pixels wide with an iteration limit of 100 by running the fractal program:
fractal 500 100
Mandelbrot sets require a significant amout of computation. The example above takes about 45 seconds on a PC with a 2.5GHz processor. A 2000-pixel wide set requires more than 15 minutes.
Have you ever written an application that uses multiple Compiler-generated libraries? Did it work as you expected? Let me know here.
- 类别:
- Deployment