Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiplatform way to determine if a dynamic library is present

I need to check if a dynamic library is present, so that later I can safely call functions that use this library.

Is there a multiplatform way to check this? I am targeting MS Windows 7 (VC++11) and Linux (g++).

like image 939
Parobay Avatar asked Apr 10 '13 12:04

Parobay


People also ask

Where can I find .so file?

These files are normally stored in /lib/ or /usr/lib/. On an Android device, SO files are stored within the APK under /lib//. Here, "ABI" can be a folder called armeabi, armeabi-v7a, arm64-v8a, mips, mips64, x86, or x86_64.

Are DLLs cross platform?

DLLs are Microsoft's implementation of the idea of a "shared library." You can only use them on platforms that, in some fashion, implement support for them. In general, this means that no, you can't just take the DLL files you have and use them on Android, or on a macOS installation, or whatever.

How dynamic libraries are loaded?

Dynamic loading is a mechanism by which a computer program can, at run time, load a library (or other binary) into memory, retrieve the addresses of functions and variables contained in the library, execute those functions or access those variables, and unload the library from memory.

Where is a dynamic library?

A dynamic library is loaded into the address space during execution runtime or launch. When loaded at execution runtime, a dynamic library is known as a "dynamically loaded library" or "dynamically linked library." When loaded at launch, a dynamic library is known as a "dynamic dependent library."

How do I use dynamic libraries in my product?

When you need to use a dynamic library in your product, you have to install the library in your computer. You may use dynamic libraries as dependent libraries (by specifying them in your product’s link line) or as runtime loaded libraries (by loading them when they are needed, using dlopen (3) OS X Developer Tools Manual Page ).

Why are dynamic libraries so often neglected?

Dynamic libraries are often neglected because they are separate from the executables and can exist anywhere on the file system. All dynamic library files should be treated like executables and strictly monitored for any changes.

How does a dynamic linker know which libraries to use?

With this approach, the dynamic linker always uses the library’s complete name when it looks for an image’s dependent libraries. An image that uses dynamic libraries as runtime-loaded libraries is smaller and loads faster than the image using the same libraries as dependent libraries.

What is a dynamic library’s install name?

This filename is known as the dynamic library’s install name. The dynamic loader uses the app’s dependent libraries’ install names to locate them in the file system.


2 Answers

To dynamically "use" a function from a shared library requires that the library isn't part of the executable file, so you will need to write code to load the library and then use the function. There may well be ways to to do that in a portable fashion, but I'm not aware of any code available to do that.

It isn't very hard code to write. As "steps", it involves the following:

  1. Load the library given a name of a file (e.g. "xx", which is then translated to "xx.so" or "xx.dll" in the architecture specific code).
  2. Find a function based on either index ("function number 1") or name ("function blah"), and return the address.
  3. Repeat step 2 for all relevant functions.
  4. When no longer needing the library, close it with the handle provided.

If step 1 fails, then your library isn't present (or otherwise "not going to work"), so you can't call functions in it...

Clearly, there are many ways to design an interface to provide this type of functionality, and exactly how you go about that would depend on what your actual problem setting is.

Edit:

To clarify the difference between using a DLL directly, and using one using dynamic loading from the code:

Imagine that this is our "shared.h", which defines the functions for the shared library (There is probably some declspec(...) or exportsymbol or other such stuff in a real header, but I'll completely ignore that for now).

 int func1();
 char *func2(int x);

In a piece of code that directly uses the DLL, you'd just do:

 #include <shared.h>

 int main()
 {
     int x = func1();
     char *str = func2(42);

     cout << "x=" << x << " str=" << str << endl;
     return 0;
 }

Pretty straight forward, right?

When we use a shared library that is dynamically loaded by the code, it gets a fair bit more complex:

 #include <shared.h>

 typedef int (*ptrfunc1)();
 typedef char * (*ptrfunc2)(int x);

 int main()
 {
     SOMETYPE handle = loadlibrary("shared");
     if (handle == ERROR_INDICATOR)
     {
         cerr << "Error: Couldn't load shared library 'shared'";
         return 1;
     }
     ptrfunc1 pf1 = reinterpret_cast<ptrfunc1>(findfunc("func1"));
     ptrfunc2 pf2 = reinterpret_cast<ptrfunc2>(findfunc("func2"));

     int x = pf1();
     char *str = pf2(42);

     cout << "x=" << x << " str=" << str << endl;
     return 0;
 }

As you can see, the code suddenly got a lot more "messy". Never mind what hoops you have to jump through to find the constructor for a QObject, or worse, inherit from a QObject. In other words, if you are using Qt in your code, you are probably stuck with linking directly to "qt.lib" and your application WILL crash if a Qt environment isn't installed on the machine.

like image 76
Mats Petersson Avatar answered Oct 12 '22 02:10

Mats Petersson


LoadLibrary calls should fail, then you can know if the dynamic library is present or not. Also with dynamic loading you get the function pointer from the dynamic library and if the pointer is null then the platform doesn't support that function on that platform.

On windows you have LoadLibrary API to load a dynamic lib. And GetProcAddress API to look up the desired function in that lib. If GetProcAddress returns NULL for that particular function that you are looking for that functionality is not present for that platform. You can log then and decide fallback.

like image 38
Abhijit-K Avatar answered Oct 12 '22 03:10

Abhijit-K