Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.145.46.18] |
|
Сообщ.
#1
,
|
|
|
Привет! Интересный вопрос возник в ходе изучения DLL:
Хочу создать универсальную ф-цию для вызова любых функций из ДЛЛ, ну скажем приблизительно такую: bool CallFunction(char *dllname,char *funcname,...){ Тут грузим ДЛЛ, пытаемся откопать адрес функции, и ...вызываем ее....,но... как достать из переменного списка аргументов функции CallFunction все типы этих аргументов, забабахать соответствующий функтор, и вызвать функцию из ДЛЛ? } В этом вся загвоздка...чтобы вызвать любую ф-цию, нужно передать ей некоторые параметры, кол-во которых различно для разных ф-ций. Ну скажем значения мы достанем при помощи va_list,va_arg и т.д., но типы-то тоже меняются, как их определить.....мммммм.......вот такая вот универсальная функция.... Есть идеи? |
Сообщ.
#2
,
|
|
|
В одном из номеров "Программиста" была статья на эту тему. Сходи на www.programme.ru.
|
Сообщ.
#3
,
|
|
|
Эврика! Все смотрим в тему "Как узнать тип переменной"......
|
Сообщ.
#4
,
|
|
|
Можно так реализовать универсальную функцию (код на VC++):
//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() или типа того |