Reflekcia, aneb ako dynamicky načítať funkcie z externej knižnice .dll pomocou LoadLibrary

                               


Celý proces reflekcie sa rozdeľuje na niekoľko častí.

Prvá časť je tvorená knižnicou, ktorá bude implementovať určité metódy. Tieto metódy budú nadobúdať príznak, že sa jedná o exportovateľné metódy.

Druhá časť je tvorená programom, ktorým načítame knižnicu a použijeme z nej metódy.
Je logické, že v časti programu, musíme vedieť, o aké metódy sa jedná - ich návratový typ a vstupné parametre.


Algoritmus:
      1. Deklaruj pointre ako typ na funkcie s rovnakými vstupnými parametrami a navratovou hodnotou,
           ako prototypy funkcií v knižnici .dll.
      2. Načítaj prostredníctvom metódy LoadLibrary knižnicu, do operačnej pamäti, z ktorej chceme
           metódy importovať.
      3. Priraď ukazateľom pretypované referencie na funkcie z knižnice, prostredníctvom GetProccAddres.
      4. Ukazatele na funkcie spusti (prípadne so vstupnými parametrami).

 

Library file: mydll.dll:
Ako prvé si v knižnici musíme deklarovať prototypy funkcií, ktoré v knižnici implementujeme.
Všetke prototypy funkcií, musia byť v bloku extern "C" a obsahovať na začiatku deklarovania promacro __declspec(dllexport).

  
   extern "C" {
       __declspec(dllexport) float GetFloat(int a, int b, int c);
       __declspec(dllexport) int Number(int a, int b);
       __declsúec(dllexport) void HelloWorld(void);
   }



Kľúčové slovo "extern" definuje, že funkcie majú byť vyditeľné v celej solutions, a __declspec definuje prekladaču, že metódy sú určené ne export. Prekladač ďalej vytvorý linker na knižnicu v podobe súbora mydll.lib.

Po deklarovaní prototypov, si ich implementujeme.


  

   float GetFloat(int a, int b, int c)
   {
       return 0.458 - (a + b) + 152.45 + c;
} int Number(int a, int b) { if(a > b) { return a; } else return b; }
void HelloWrld(void) { ::std::cout << "\n HelloWorld"; }





V programe program.exe:

  

   #include <windows.h>
   #include <fstream>
   #include <iostream>
   
   typedef float (*fnca)(int a, int b, int c);
   typedef int (*fncb)(int a, int b);
   typedef void (*fncc)(void);


   int _cdecl main (void)
   {
       fnca dllfunctionA;
       fncb dllfunctionB;
       fncc dllfunctionC;

       HINSTANCE instance = LoadLibraryA("mydll.dll");
       dllfunctionA = (fnca)GetProcAddress(instance, "GetFloat");
       dllfunctionB = (fncb)GetProcAddress(instance, "Number");
       dllfunctionC = (fncc)GetProcAddress(instance, "HelloWorld");

       ::std::cout << dllfunctionA(8, 2, 5);
       ::std::cout << "\n";
       ::std::cout << dllfunctionB(50, 80);
       ::std::cout << "\n";
       dllfunctionC ();
       ::std::cout <<"\n\n";

       system("pause");

       return 0;
   }



Celý príklad je na videu tu: