Explicit Linking in C

Explicit linking is the process of linking a dynamic link library at run time explicitly by user. There are two types of linking - static and dynamic. Static linking is build time linking. Code of the static library adds to the binary during compilation/linking time. Now dynamic linking is the process where application is compiled without library binary. The library is loaded during load time. Implicit linking is the process where OS loader loads the dependent library. Explicit Linking is the process where user loads the library using loader APIs and fetches the symbol load address and calls explicitly.

Windows Explicit Linking

When application does not links the external symbol by import library rather it loads the DLL at runtime. It does the same mechanism as operating system does during loading of the implicit linked DLL calls.

This is done by using Win32 APIs like :

  • LoadLibrary() - loads and links a input library form the DLL path, or current path,
  • GetProcAddress() - finds the symbol/function address by its name for a loaded DLL
  • FreeLibrary() - unloads the loaded DLL instance

Windows DLL project

mathlib-dll-project

mathlib-dll-project-2

mathlib-dll-project-3

mathlib-dll-project-build

#include "stdafx.h"

extern "C" __declspec(dllexport) int add (int a, int b)
{
  return (a + b);
}

extern "C" __declspec(dllexport) int sub (int a, int b)
{
  return (- b);
}

extern "C" __declspec(dllexport) int mul (int a, int b)
{
  return (* b);
}

extern "C" __declspec(dllexport) int div (int a, int b)
{
  return (/ b);
}

BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
           )
{
    return TRUE;
}


Windows App project

mathapp-project-1

mathapp-project-2

mathapp-project-3

mathapp-project-build

mathapp-project-dll-copy

mathapp-project-dll-explicit

#include "stdafx.h"
#include <windows.h>

/*Example of Explicit Call*/
typedef int (add_proc)(int a, int b);
int main(int argc, char *argv[])
{
  add_proc *add;
  HINSTANCE h_dll;
  int a = 1, b = 2, c;
  h_dll = LoadLibrary("mathlib.dll");/*Explicit Load*/
  if(h_dll)
  {
    printf("LoadLibrary returns %x\n", h_dll);
    add = (add_proc *)GetProcAddress(h_dll, "add");
    if(add)
    {
      printf("GetProcAddress returns add = %x\n", add);
      c = add(a, b); /*Explicit Call*/
      printf("add %d + %d = %d\n", a, b, c);
    }
    else
    {
      printf("add() not found in mathlib.dll");
    }
    FreeLibrary(h_dll);
  }
  else
  {
    printf("Unable to load mathlib.dll");
    return(-1);
  }
  return 0;
}

Linux Explicit Linking

Let us consider once again math.c file for explicit linking. The steps for creating a shared library are same as that of implicit linking.
First we compile it with position independent flag on(-fPIC). This is needed for dynamic/static linking.
$cc -fPIC -c mathlib.c -o mathlib.o

Now make a shared library with the object file.
$cc -shared -o libmath.so mathlib.o

To use this shared library in a application we need to load the library then find the function pointer address, invoke the function, and at last unload the library.
Linux provides some dynamic link library APIs to achieve this. Her are some useful frequently use APIs:

  • dlopen() - loads a dynamic link binary
  • dlsym() - returns the function pointer if found the function entry
  • dlclose() - unloads the dynamic link binary

Linux SO project

linux-mathlib-source

int add (int a, int b)
{
  return (a + b);
}

int sub (int a, int b)
{
  return (- b);
}

int mul (int a, int b)
{
  return (* b);
}

int div (int a, int b)
{
  return (/ b);
}

Linux App project

linux-mathapp-source

#include<stdio.h>
#include<dlfcn.h>

typedef int (add_func) (int a, int b);
void *lib_handle = NULL;
add_func * add;
int main (int argc, char *argv[])
{
  int a = 1, b = 2, c;
  lib_handle = (void *)dlopen("./libmath.so", RTLD_LAZY); 
  if(lib_handle) 
  {
    printf("dlopen returns %p\n", lib_handle);
    add = dlsym(lib_handle, "add");
    if(add)
    {
      printf("dlsym returns add = %p\n", add);
      c = add (a, b);
      printf("%d + %d = %d\n", a, b, c);
    }
    else
    {
      printf("Function entry not found in DLL");
    }
    dlclose(lib_handle);
  }
  else
  {
    printf("Unable to open DLL");
  }
}



SO and App build and run

linux-mathapp-source

About our authors: Team EQA

You have viewed 1 page out of 248. Your C learning is 0.00% complete. Login to check your learning progress.

#