#include <windows.h>
#include <stdio.h>
int WINAPI main()
{
HINSTANCE hinstLib = LoadLibrary("my.dll");
if (hinstLib == NULL) {
printf("ERROR: unable to load DLL\n");
return 1;
} else {
printf("Ok, loaded hinstLib = %d\n", hinstLib);
int __stdcall *DllGetVersion = (int __stdcall *) GetProcAddress(hinstLib, "myFunc");
if (DllGetVersion == NULL) {
printf("ERROR: unable to find DLL function\n");
return 1;
}
// Каким образом здесь вызвать myFunc из DLL-ки,
// от которой нет исходников, но знаю что вызовы там должны быть stdcall,
// с переменным количеством передаваемых аргументов?
//
// Наример:
// int n = 3;
// int a[];
// нужно вызвать myFunc(a[0],a[1],a[2]);
// а n - имеет обыкновение меняться
// и возможно a[i] - будут иметь разные типы
FreeLibrary(hinstLib);
}
return 0;
}
Re: Вызвать функцию из DLL с любым количеством аргуметнов
Здравствуйте, vasilyev, Вы писали:
V>...Вот нашел (http://www.drizzle.com/~scottb/gdc/ — статья за 2001 год, очень рекомендую), вроде пошло, счас буду ковыряться:
V>
V>DWORD Call_stdcall( const void* args, size_t sz, DWORD func )
V> {
V> DWORD rc; // here's our return value...
V> __asm {
V> mov ecx, sz // get size of buffer
V> mov esi, args // get buffer
V> sub esp, ecx // allocate stack space
V> mov edi, esp // start of destination stack frame
V> shr ecx, 2 // make it dwords
V> rep movsd // copy it
V> call [func] // call the function
V> mov rc, eax // save the return value
V> }
V> return (rc);
V> }
Статью не читал, но смысл этого кода — вызвать функцию __stdcall с фиксированным количеством аргументов (переменное кол-во не возможно по конвенции __stdcall в принципе).
Если этой прокси-функции передать, скажем, 5 DWORD аргументов (sz == 20) и вызвать __stdcall функцию, которая принимает только 2 аргумента, последняя просто проигнорирует 3 лишних. Единственный эффект — не упадёт при возврате из И этот код не работает при sz не кратном 4.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[3]: Вызвать функцию из DLL с любым количеством аргуметнов
...Признаюсь, плохо объяснил. Функция — в DLL принимает — фиксированное кол-во аргументов.
Но только програмку надо написать такую, чтобы она могла вызывать любую функцию (а соответственно с заведомо неизвестным количеством аргументов)
Конечная цель такая:
class DLLValue {
char* value;
int type;
}
class DLLHandler {
...
public:
int load(char* dllFileName);
int call(char* funcName, DLLValue* args, int count, void* DLLValue) {
// Здесь проблема
}
}
Re[5]: Вызвать функцию из DLL с любым количеством аргуметнов
V>...Признаюсь, плохо объяснил. Функция — в DLL принимает — фиксированное кол-во аргументов. V>Но только програмку надо написать такую, чтобы она могла вызывать любую функцию (а соответственно с заведомо неизвестным количеством аргументов)
так а в чём проблема? — известно кол-во аргументов и их типы.... пихаешь их в стек в соответствии с calling convention вызываемой ф-ции и вызываешь саму ф-цию только писать на асме, видимо, надо
Homo sum et nihil humani a me alienum puto...
Re[6]: Вызвать функцию из DLL с любым количеством аргуметнов
Здравствуйте, Вумудщзук, Вы писали:
V>>...Признаюсь, плохо объяснил. Функция — в DLL принимает — фиксированное кол-во аргументов.
Значит, известно максимально возможное количество аргументов.
V>>Но только програмку надо написать такую, чтобы она могла вызывать любую функцию (а соответственно с заведомо неизвестным количеством аргументов) В>так а в чём проблема? — известно кол-во аргументов и их типы.... пихаешь их в стек в соответствии с calling convention вызываемой ф-ции и вызываешь саму ф-цию только писать на асме, видимо, надо
Или воспользоваться "С++ эмуляцией переменного кол-ва параметров"
template<typename T1>
int call(char* funcName, T1 arg1);
template<typename T1, typename T2>
int call(char* funcName, T1 arg1, T2 arg2);
template<typename T1, typename T2, typename T3>
int call(char* funcName, T1 arg1, T2 arg2, T3 arg3);
//...
Ещё есть вариант для любителей каст, но я слабо уверен, что ничего не напутал со скобочками
int call(char* funcName, DLLValue* args, int count, void* DLLValue)
{
typedef int (__stdcall * ptr_to_fun_0)();
typedef int (__stdcall * ptr_to_fun_1)(void*);
//...void * fun = GetProcAddress(...
switch ( count )
{
case 0: return ((ptr_to_fun_0)fun)();
case 1: return ((ptr_to_fun_1)fun)((void*)arg1);
//...
}
}
Но этот ИМХО плохой, как и вариант с асмом. Непонятно, как он поведёт себя на разных хитрых типах вроде long double, или когда функции возвращают сложные типы.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re: Вызвать функцию из DLL с любым количеством аргуметнов