4. dynamic library to create and use our last to introduce a dynamic loading of shared libraries, or as a dynamic link library.
It is characterized by the application is running, when you need to fit into memory, rather than the shared library so that when the application starts the program library is loaded into memory. To this end, we would also like to build shared in front of the target file, as follows: $ gcc-fPIC-cinitapi.c $ gcc-fPIC-crandapi.c $ gcc-sharedinitapi.orandapi.o-
olibmyrand.so $ su-$ cplibmyrand.so/usr/local/lib $ exit here, we will put our shared library to a public location, i.e./usr/local/lib directory. Just as we can see, static libraries and shared libraries are generally talk application binary files are placed in the same directory, in contrast, dynamic link libraries are generally placed in/usr/local/lib directory. This library as the original shared library is functionally equivalent, just the application uses them. It is important to note that in order to make our library is copied to the root/usr/local/lib requires permission. To do this, you can first use the su command to become root user. Now, we have rebuilt their own shared library, the next step is our test program how to dynamically use it. To do this, we need to test the program to access the API methods to make some modifications. Then, we'll look at how to build using the dynamic-link library programs. Updated test program code as shown below://used in the dynamic link library test program # include
# include # include # include "randapi." # DefineITERATIONS1000000Lintmain () {longisum longi;;; void * handle floatfsum; char * err; void (* initRand_d) (void); float (* getSRand_d) (void); int (* getRand_d) (int);//open a handle to the dynamic library handle = dlopen ("/usr/local/lib/libmyrand.so", RTLD_LAZY); if (handle = = (void *) 0) {fputs (dlerror (), stderr); exit (-1);} //Check for initRand () function accesses initRand_d = dlsym (handle, "initRand"); err = dlerror (); if (err! = NULL) {fputs (err, stderr); exit (-1);} //Detection on getSRand () function accesses getSRand_d = dlsym (handle, "getSRand"); err = dlerror (); if (err! = NULL) {fputs (err, stderr); exit (-1);} //Check getRand () function accesses getRand_d = dlsym (handle, "getRand"); err = dlerror (); if (err! = NULL) {fputs (err, stderr); exit (-1);} //Initialize random number API (* initRand_d) ();//calculate getRand (10) returns the value of average 0L isum =; for (I = 0; I
Printf ("getRand () Average% d\n", (int) (isum/ITERATIONS));//calculate getSRand () function returns the value of average fsum = 0.0; for (I = 0; I
Printf ("getSRand () Average% f\n", ((float) fsum/ITERATIONS));//close the dynamic library handles dlclose (handle); return;} Compared with the previous code, you may find here some convoluted, but as long as you understand the DLAPI works, all problems solved. The real intention here is to use dlopen open shared object file, and then through dlsym let a local function pointer points to the shared object file function. This allows us to after the application calls the function. After you finish these, use dlclose close shared libraries, clear all references, that is, the release for the interface all the memory allocated. In order to be able to use these DLAPI, we need to include in the application header file dlfcn.h. Use dynamic library is the first step in using dlopen to open it, where the code is: handle = dlopen ("/usr/local/lib/libmyrand.so", RTLD_LAZY); we will not only require the library you want to use (in this case as/usr/local/lib/libmyrand.so), in addition to the provisions of a flag will have.We here may be used to flag has two, RTLD_LAZY and RTLD_NOW, RTLD_LAZY, it will in future use when resolving a reference only; if you require flag RTLD_NOW, it will load the library when resolving references. If the function returns the dlopen is an opaque handle, the library is open. Note that if an error occurs, we can use the dlerror function to stdout or stderr output an error message. In addition, if necessary, we can create a shared library called _init function, so that through dlopen open our shared libraries, it will call this function to initialize. Because the dlopen function always returns to the caller before calling the _init function. Next, let's look at how reference library functions, or how to pass the function name to call a library function. First look at the following code: initRand_d = dlsym (handle, "initRand"); err = dlerror (); if (err! = NULL) {fputs (err, stderr); exit (-1);} This code fragment can be seen, the process is very simple. API function dlsym will in our shared library search-defined function, for the purposes of this case is to be found in initialization function initrand. If found, returns a void * pointer, and put it into a local function pointer variable, so that you can call this function to carry out the actual initialization. We automatically check error state, if the returned error string, then the string will be issued and exit the application. This is found we want to call the shared library functions. Gets the initrand function pointers, we also get the getRand getSRand and function pointers. Our test program basic unchanged, just not directly call a function, but instead uses the pointer to the function of the interface to indirectly call them. We see that although the dynamic loading of interface improvements in flexibility, but performance was slightly losses. In the new test procedures, the final step is to close the program library, which is passed to API function dlclose. If the API found no other users then use the shared libraries, it will be uninstalled. Similar to dlopen, dlclose, and also provide a mechanism for sharing the destination file can be exported through the mechanism to a completion routine, so that when calling the API function when the complete dlclose routines. Developers only need to add a field called a shared library of functions, dlclose _fini will return before calling _fini function. See the bar, although a small number of changes required, the application uses the dynamic loading of shared libraries, not only brings more flexibility and significant savings in memory (see earlier in Figure 1 and Figure 2). Note that when the application starts, and do not require all dynamic function on it are visible. On the contrary, the only program running to need these functions will be to load dynamic library, prior to this, the program never actually need them. A dynamically loaded library API is very simple, for completeness we described briefly: void * dlopen (constchar * filename, intflag); constchar * dlerror (void); void * dlsym (void * handle, char * symbol); intdlclose (void * handle);
No comments:
Post a Comment