![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
вызов функции из DLL динамически. [D7, WinXP]
TakTak © (2006-09-27 15:13:00)проблеммка такова, что нужно грузить разные функции из подключаемых dll. вместе с dll идет файл "компановки", т.е. описания всех функций и их параметров. так вот, надо динамически грузить всё то, что есть в файле "компановки DLL". Кто чего может подсказать, как это реализовать??
zamtmn (2006-09-27 19:33:00) [1]function Sum (a : real; b : real) : real ;
такой вид функций обязателен? это придется почтишто компилятор написать:)
можно всё сильно упростит создав свой стек параметров
будешь иметь унифицированный вызов всех процедур
procedure Sum (p:pstack;ctackheap:integer);
в длл выбираешь из p^ два значения, суммируешь и помещаешь обратно, наподобии как FPU работает
zamtmn (2006-09-27 19:24:00) [2]>>Для cdecl думаю можно обойтись без asm и достаточно одного объявления на все случаи жизни.
>> I := F(1, 2, 'Hello');
в comtiletime о (1, 2, 'Hello') никто ниче не знает, для всех соглашений о вызовах стек придется формировать runtime
guav (2006-09-27 16:27:00) [3]> [15] clickmaker © (27.09.06 16:10)
> если больше, то ты должен передать адрес, по которому лежит
> значение
Это для pascal/register, для stdcall записи длинее 32 бит тоже идут в стек.
>TakTak
Для cdecl думаю можно обойтись без asm и достаточно одного объявления на все случаи жизни.
var F: function: Int64; cdecl varargs;
function Test(A, B: Integer; S: PChar): Integer; cdecl; // эта типа в длл и мы её не знаем её прототипа.
begin
ShowMessage(S);
Result := A + B;
end;
procedure TForm1.FormCreate(Sender: TObject);
var I: Integer;
begin
@F := @Test;
I := F(1, 2, 'Hello');
Caption := IntToStr(I);
end;
Для stdcall или другой конвенции можно написать для всех функций одну обёртку, что-то вроде
function CallFcn(FcnAddr: Pointer;
Parameters: Pointer; ParamSize: Integer): Int64;
asm
// Здесь код помещающий Parameters в стек и вызывающий FcnAddr
end;
TakTak (2006-09-27 16:19:00) [4]спасибо, пошел разбираться !
clickmaker (2006-09-27 16:10:00) [5]
> а выделение памяти, заполнение стека
если у тебя параметры там размером не более 32-бит, то достаточно push paramValue
если больше, то ты должен передать адрес, по которому лежит значение
TakTak (2006-09-27 16:06:00) [6]а выделение памяти, заполнение стека ..... вот так просто push и всё ?
clickmaker (2006-09-27 16:03:00) [7]
> чуть подробнее ???? плз !!!
куда уж подробнее
asm // начало ассамблерного кода
push param1 // заталкиваем в стек параметр
call fn // вызываем функцию по ее адресу
end;
тут нужно еще учесть, как функция объявлена в DLL - stdcall, cdecl. От этого зависит очередность параметров в стеке
TakTak (2006-09-27 15:56:00) [8]парсинг и прочее - всё готово.
вот вот !!! на счет азма можно чуть подробнее ???? плз !!!
clickmaker (2006-09-27 15:51:00) [9]
> [9] TakTak (27.09.06 15:45)
хм... ну что я могу сказать.... Если формат этого файла компановки может быть только таким, то остается только его парсить.
К примеру, получил имя функции
fn := GetProcAddress(hLib, FuncName);
получил параметры и дальше
asm
push param1
...
call fn
end;
что-то типа
TakTak (2006-09-27 15:47:00) [10]из файла funct.txt она узнает о подключаемых функциях, грузит их из funct.dll и вызывает их по требованию, а требование определает исполняемый файл
TakTak (2006-09-27 15:45:00) [11]есть, по сути это обычный интерпретатор, т.е. мини скриптовой язык. просто акромя этих двух файлов, есть еще и третий - исполняемый.
к примеру такого одержания:
a := Sum(10,20) ;
b := sumstr('тест',' удачный') ;
clickmaker (2006-09-27 15:37:00) [12]
> программа должна сама автоматически определить что появился
> новый модуль (длл), считать описание его (txt) и выполнить
> функции
это как? все подряд, по списку? а нафига?
Логика-то какая-то есть у программы?
TakTak (2006-09-27 15:34:00) [13]мне тут подсказали, что подобное надо собирать с использованием asm-а, но я в нем не волоку.
Palladin (2006-09-27 15:32:00) [14]фигасе...
TakTak (2006-09-27 15:29:00) [15]поясняю ...
дали мне файл funct.dll и файл funct.txt
файл funct.txt - файл компановки.
его содержание
function Sum (a : real; b : real) : real ;
function SumStr (a : string; b : string) : string ;
Мне надо засунуть эти два файла в папку с программой и запустить её. программа должна сама автоматически определить что появился новый модуль (длл), считать описание его (txt) и выполнить функции
clickmaker (2006-09-27 15:22:00) [16]а это что?
> вместе с dll идет файл "компановки", т.е. описания всех
> функций и их параметров
TakTak (2006-09-27 15:22:00) [17]>> clickmaker
И как ты будешь передавать параметры - ума не приложу!
TakTak (2006-09-27 15:21:00) [18]>> clickmaker
эти функции я прекрасн знаю. Дело в том что мы заранее не знаем ни имени функции ни количество параметров, и тем более их типы!!! интересно как с помощью их ты это зделаешь!!!????
clickmaker (2006-09-27 15:14:00) [19]LoadLibrary(), GetProcAddress()