На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
  
> Универсальная функция для DLL
    Привет! Интересный вопрос возник в ходе изучения DLL:
    Хочу создать универсальную ф-цию для вызова любых функций из ДЛЛ, ну скажем приблизительно такую:

    bool CallFunction(char *dllname,char *funcname,...){

    Тут грузим ДЛЛ, пытаемся откопать адрес функции, и ...вызываем ее....,но...
    как достать из переменного списка аргументов функции CallFunction
    все типы этих аргументов, забабахать соответствующий функтор, и вызвать функцию из ДЛЛ?

    }

    В этом вся загвоздка...чтобы вызвать любую ф-цию, нужно передать ей некоторые
    параметры, кол-во которых различно для разных ф-ций.

    Ну скажем значения мы достанем при помощи va_list,va_arg и т.д., но типы-то тоже меняются, как их определить.....мммммм.......вот такая вот универсальная функция....

    Есть идеи?
      В одном из номеров "Программиста" была статья на эту тему. Сходи на www.programme.ru.
        Эврика! Все смотрим в тему "Как узнать тип переменной"......
          Можно так реализовать универсальную функцию (код на VC++):
          ExpandedWrap disabled
             
            //extern "C" void __declspec( dllexport ) __stdcall UniversalCall()
            void __stdcall UniversalCall(/*"name of dll", "proc", args*/)
            {
                // Здесь используем первые 2 параметра ("имя длл", "имя функции")
                // для вызова LoadLibrary/FreeLibrary и GetProcAddress, а остальные параметры (если
                // они есть) передаем в функцию, адрес которой получаем с помощью GetProcAddress
             
                static HMODULE hModule = (HMODULE)0;
                static DWORD dwLoadLibrary = (DWORD)::LoadLibrary;
                static DWORD dwFreeLibrary = (DWORD)::FreeLibrary;
                static DWORD dwGetProcAddress = (DWORD)::GetProcAddress;
                static DWORD dwAddr = (DWORD)0;
                static FARPROC ProcAddr = (FARPROC)0;
                static DWORD dwEBP = (DWORD)0;
                __asm {
                    mov eax, [ebp]
                    mov dwEBP, eax
             
                    mov eax, ebp
                    add eax, 08h
                    push [eax]
                    call dwLoadLibrary
                    mov hModule, eax
             
                    mov eax, ebp
                    add eax, 0Ch
                    mov eax, [eax]
                    push eax
                    push hModule
                    call dwGetProcAddress
                    mov ProcAddr, eax
             
                    mov esi, ebp
                    add esi, 4
                    mov esi, [esi]
                    mov dwAddr, esi
                    lea ebx, label_A
                    mov [ebp + 0Ch], ebx
                    mov eax, ebp
                    add eax, 0Ch
                    mov esp, eax
                    jmp ProcAddr
            label_A:
                    push hModule
                    call dwFreeLibrary
                    mov ebp, dwEBP
                    jmp dwAddr
                }
            }
             
             
            void CFDlg::OnOK()
            {
                //Юзаем UniversalCall:
                char * szProc1 = "MessageBoxA";
                char * szProc2 = "MessageBeep";
                char * szDll = "user32";
                __asm{
                    //Вызываем MessageBoxA:
                    push MB_OK
                    push szDll
                    push szProc1
                    push 0
                    lea eax, szProc1
                    push [eax]
                    lea eax, szDll
                    push [eax]
                    call UniversalCall
             
                    //Вызываем MessageBeep:
                    push -1
                    lea eax, szProc2
                    push [eax]
                    lea eax, szDll
                    push [eax]
                    call UniversalCall
                }
            }


          UniversalCall() у меня не получилось написать так как VC++ делает ее __cdecl, поэтому UniversalCall() нужно юзать как я показал в CFDlg::OnOK() или типа того :(
          Сообщение отредактировано: Bjarne Stroustrup -
          1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
          0 пользователей:


          Рейтинг@Mail.ru
          [ Script execution time: 0,0553 ]   [ 15 queries used ]   [ Generated: 17.05.24, 09:48 GMT ]