Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

invoking shared library loader from c code

Tags:

c++

c

gcc

I have a shared library that I would like to load twice in my program. The use case is as following:

  • Open program (and load library)
  • Call Function F1() from library
  • detach library from program
  • load library again and re-initialize all variables
  • Call Function F1() from library again

Is there a way from C/C++ code to do this? I am interested in a solution that works with gcc/g++

like image 455
siwesam Avatar asked Feb 06 '26 21:02

siwesam


1 Answers

At first I was thinking about LoadLibrary, GetProcAddress and FreeLibrary but then I mentioned that you want gcc/g++, which looks like you need *NIX solution. So I just have stolen solution from here:

loadlib.h

#ifndef  __LOADLIB_H
#define  __LOADLIB_H

#ifdef UNIX
#include <dlfcn.h>
#endif 

#include <iostream>
using namespace std;

typedef void* (*funcPtr)();

#ifdef UNIX
#  define IMPORT_DIRECTIVE __attribute__((__visibility__("default")))
#  define CALL  
#else
#  define IMPORT_DIRECTIVE __declspec(dllimport) 
#  define CALL __stdcall
#endif

extern "C" {
  IMPORT_DIRECTIVE void* CALL LoadLibraryA(const char* sLibName); 
  IMPORT_DIRECTIVE funcPtr CALL GetProcAddress(
                                    void* hModule, const char* lpProcName);
  IMPORT_DIRECTIVE bool CALL  FreeLibrary(void* hLib);
}

#endif

Loadlib.cpp

#include "loadlib.h"

int main(int argc, char* argv[])
  {
  #ifndef UNIX
    char* fileName = "hello.dll";
    void* libraryHandle = LoadLibraryA(fileName);
    if (libraryHandle == NULL)
      cout << "dll not found" << endl;
    else  // make a call to "printHello" from the hello.dll 
      (GetProcAddress(libraryHandle, "printHello"))();
    FreeLibrary(libraryHandle);
#else // unix
    void (*voidfnc)(); 
    char* fileName = "hello.so";
    void* libraryHandle = dlopen(fileName, RTLD_LAZY);
    if (libraryHandle == NULL)
      cout << "shared object not found" << endl;
    else  // make a call to "printHello" from the hello.so
      {
      voidfnc = (void (*)())dlsym(libraryHandle, "printHello"); 
      (*voidfnc)();
      }
    dlclose(libraryHandle);
  #endif

  return 0;
  }
like image 114
mvidelgauz Avatar answered Feb 08 '26 10:02

mvidelgauz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!