Difference of usage between shared and static library

361 views Asked by At

I have a very simple sample of code :

#include<iostream>
#include "libMPSSE_spi.h"

int main() {
   uint32 channels = 0;
   std::cout << "erreur = " <<  SPI_GetNumChannels(&channels) << std::endl;
   std::cout << "Number of available SPI channels = " << (int)channels << std::endl;
   return 0;
}

That works fine when I link the static libMPSSE, but has an issue with the shared library.

My two commands to build the file are :

g++ test.cpp -o test.o -I../../libs/MPSSE -I../../libs/FTDI/linux -L../../libs/MPSSE/linux/x64 -lMPSSE

g++ test.cpp -o test.o -I../../libs/MPSSE -I../../libs/FTDI/linux ../../libs/MPSSE/linux/x64/libMPSSE.a -ldl

Both compilation works, but the execution output is not the same. With static linking the library works fine, and with dynamic linking it returns "other error".

Note : I have built both library myself with the provided makefile (object are built before the same way for both libraries):

libMPSSE:   $(OBJECTS)
    $(CC)  -o libMPSSE.so -shared $(OBJECTS) -L /MinGW/lib -ldl
    $(AR) rcs libMPSSE.a $(OBJECTS)

What could explain the different behavior of both libraries?

Note : in the example they provide with their library, they use the shared library with dlopen but if I have the library and header at link time, I shouldnt have to do that?

Note2 : they both use libftd2xx.so and I use this command to run the executable (dynamic and static)

LD_LIBRARY_PATH=~/WS/Qt/main/LC4/main/libs/FTDI/linux/x64:~/WS/Qt/main/LC4/main/libs/MPSSE/linux/x64 ./test.o
LD_LIBRARY_PATH=~/WS/Qt/main/LC4/main/libs/FTDI/linux/x64 ./test.o

Edit : code that work with shared library (from their example)

#include <iostream>
#include "libMPSSE_spi.h"
#include <dlfcn.h>


int main() {

    typedef FT_STATUS (*pfunc_SPI_GetNumChannels)(uint32 *numChannels);
    pfunc_SPI_GetNumChannels p_SPI_GetNumChannels;
    void *h_libMPSSE;

    h_libMPSSE = dlopen("../../libs/MPSSE/linux/x64/libMPSSE.so",RTLD_LAZY);
    if(!h_libMPSSE)
    {
        std::cout <<"Failed loading libMPSSE.so. Please check if the file exists in ";
        std::cout << "the shared library folder(/usr/lib or /usr/lib64)" << std::endl;
        return 1;
    }
    p_SPI_GetNumChannels = (pfunc_SPI_GetNumChannels)dlsym(h_libMPSSE, "SPI_GetNumChannels");

   uint32 channels = 0;
   std::cout << "erreur = " <<  p_SPI_GetNumChannels(&channels) << std::endl;
   std::cout << "Number of available SPI channels = " << (int)channels << std::endl;
   return 0;
}
1

There are 1 answers

1
user45891 On

As your program is loaded and initialized the operating system searches for the required shared libraries in the appropriate directories (e.g. /usr/lib or %WINDIR%\system32)*.

If that library is not present in those directories the application will not run, as the dependency isn't met. Your example probably advises you to use dlopen to load the shared library from the same directory your application is in - you might no be able to copy your shared library into the default paths without administrator rights.

* usually you can add more paths to be searched but those are the default ones