[c++] deklaracja wskaźnika na funkcje.

0

Witam. Zaczynam dopiero zabawę z c++. Napotkałem taki problem:
Potrzebuję zadeklarować wskaźnik na funkcje ... tyle, że w momencie gdy go deklaruję w programie nie wiem jeszcze jaki będzie prototyp tej funkcj (to są informacje pobierane od usera).
Oto schemat działania programu w uproszczeniu:

//          PROGRAM POBIERA OD USERA NAZWE BIBLIOTEKI DLL ORAZ 
//          NAZWE FUNKCJI EXPORTOWANEJ PRZEZ TA BIBLIOTEKE.
//          NASTEPNIE MIERZY CZAS JEJ WYKONANIA I WYSWIETLA
//          WYNIK POMIARU:
//
//          01).    - LADOWANIE BIBLIOTEKI KTOREJ NAZWA ZNAJDUJE SIE 
//                      W POLU IDC_EDIT_LIBRARY.
//          02).    - POBIERANIE ADRESU FUNKCJI KTOREJ NAZWA ZNAJDUJE SIE 
//                      W POLU IDC_EDIT_FUNCTION.
//          03).    - POBIERANIE TIMERAX (QueryPerformanceCounter).
//          04).    - WYWOLANIE FUNKCJI KTOREJ ADRES ZOSTAL USTALONY 
//                      W PUNKTACH. 01, 02.
//          05).    - PONOWNY POMIAR CZASU (TIMERY).
//          06).    - OBLICZANIE ROZNICY CZASU.
//          07).    - WYSWIETLANIE CZASU WYKONANIA.
 

oto fragment kodu z problemem:

            HMODULE lhmod = LoadLibrary(libname);
            if (lhmod == NULL)
            {
                ShowError("NIE MOZNA ZALADOWAC PODANEJ BIBLIOTEKI");
                break;
            }
            FARPROC lpfn = GetProcAddress(lhmod, fname);
            if (lpfn == NULL)
            {
                ShowError ("NIE MOZNA UZYSKAC ADRESU \
                                 WSKAZANEJ PROCEDURY");
                break;
            }
            QueryPerformanceCounter(&tx);
            (lpfn) ();
            QueryPerformanceCounter(&ty);
 

W takim ukladzie dziala tylko dla funkcji bez argumentowej np. kernel32.dll\GetLastError

Niby przychodzi mi do głowy rozwiązanie - tyle, że wymagało by wstawki asemblera gdzie wrzucam argumenty na stos przed wywołaniem testowanej fukcji.
No tyle, że właśnie chciał bym to w c++ zrealizować. Da się to zrobić ?

0

Przecież poza samą nazwą funkcji musisz jeszcze znać jej argumenty oraz podać wartości na samo wywołanie.

Chyba tylko va_list
http://www.cplusplus.com/reference/cstdarg/va_list/

musisz jeszcze wziąć pod uwagę, że funkcje WinAPI są jako __stdcall, a jeśli chcesz wołać funkcje z innych DLLek to musisz też wiedzieć w jakiej konwencji są (poza nazwą parametrami)

0
typedef double (FAR WINAPI *FARMYPROC) (double,double);
FARMYPROC lpfn = GetProcAddress(lhmod, fname);
double x=lpfn(3.3,4.4);
0

Zrób sobie zwykły wskaźnik typu void i przypisz do niego funkcję którą chcesz wywołać. Później pobierasz informację jak powinna wyglądać deklaracja funkcji od usera. Później musisz wykonać odpowiednie rzutowanie tego wskaźnika na voida na inny typ w zależności od tego co podał user. Ogólnie musisz z tym rzutowaniem pokombinować. Innego pomysłu nie mam.

0

Sorka nie doczytałem się dokładnie, zawsze możesz zrobić taki myk:
struct STOS
{
unsigned char tb[128];
};

typedef void (FAR WINAPI *FARMYPROC) (STOS);
FARMYPROC lpfn = GetProcAddress(lhmod, fname);
STOS S;
//tu trzeba w ten S.tb odpowiednio wpakować informacje.
lpfn(S);

#include <iostream>
#include <cstring>
using namespace std;

struct STOS
  {
   unsigned char tb[128];
  };

typedef void (*FARMYPROC)(STOS);

void fd(double x)
  {
   cout<<x<<endl;
  }

void fdd(double x,double y)
  {
   cout<<x<<' '<<y<<endl;
  }

void fdcd(double x,char c,double y)
  {
   cout<<x<<' '<<c<<' '<<y<<endl;
  }

int main()
  {
   STOS S;
   FARMYPROC fun;
   double x=3.33,y=7.77;
   char ch='*';

   fun=(FARMYPROC)(void*)&fd;
   memcpy(S.tb,&x,sizeof(double));
   fun(S);
   
   fun=(FARMYPROC)(void*)&fdd;
   memcpy(S.tb,&x,sizeof(double));
   memcpy(S.tb+sizeof(double),&y,sizeof(double));
   fun(S);

   fun=(FARMYPROC)(void*)&fdcd;
   memcpy(S.tb,&x,sizeof(double));
   memset(S.tb+sizeof(double),0,sizeof(unsigned));
   memcpy(S.tb+sizeof(double),&ch,sizeof(char));
   memcpy(S.tb+sizeof(double)+sizeof(unsigned),&y,sizeof(double));
   fun(S);

   cin.sync();
   cin.get();
   return 0;
  }
0

Nie no sory za zamieszanie w ogóle źle się zabrałem do tego. Program testujący musi podawać parametry dla testowanej funkcji - bez interpretera się nie obejdzie. Dopiero później coś w tym stylu jak 13 smok nakreślił.

1 użytkowników online, w tym zalogowanych: 0, gości: 1