Текущий архив: 2006.10.15;
Скачать: CL | DM;
Внизвызов функции из DLL динамически. Найти похожие ветки
← →
TakTak (2006-09-27 15:13) [0]проблеммка такова, что нужно грузить разные функции из подключаемых dll. вместе с dll идет файл "компановки", т.е. описания всех функций и их параметров. так вот, надо динамически грузить всё то, что есть в файле "компановки DLL". Кто чего может подсказать, как это реализовать??
← →
clickmaker © (2006-09-27 15:14) [1]LoadLibrary(), GetProcAddress()
← →
TakTak (2006-09-27 15:21) [2]>> clickmaker
эти функции я прекрасн знаю. Дело в том что мы заранее не знаем ни имени функции ни количество параметров, и тем более их типы!!! интересно как с помощью их ты это зделаешь!!!????
← →
TakTak (2006-09-27 15:22) [3]>> clickmaker
И как ты будешь передавать параметры - ума не приложу!
← →
clickmaker © (2006-09-27 15:22) [4]а это что?
> вместе с dll идет файл "компановки", т.е. описания всех
> функций и их параметров
← →
TakTak (2006-09-27 15:29) [5]поясняю ...
дали мне файл funct.dll и файл funct.txt
файл funct.txt - файл компановки.
его содержание
function Sum (a : real; b : real) : real ;
function SumStr (a : string; b : string) : string ;
Мне надо засунуть эти два файла в папку с программой и запустить её. программа должна сама автоматически определить что появился новый модуль (длл), считать описание его (txt) и выполнить функции
← →
Palladin © (2006-09-27 15:32) [6]фигасе...
← →
TakTak (2006-09-27 15:34) [7]мне тут подсказали, что подобное надо собирать с использованием asm-а, но я в нем не волоку.
← →
clickmaker © (2006-09-27 15:37) [8]
> программа должна сама автоматически определить что появился
> новый модуль (длл), считать описание его (txt) и выполнить
> функции
это как? все подряд, по списку? а нафига?
Логика-то какая-то есть у программы?
← →
TakTak (2006-09-27 15:45) [9]есть, по сути это обычный интерпретатор, т.е. мини скриптовой язык. просто акромя этих двух файлов, есть еще и третий - исполняемый.
к примеру такого одержания:
a := Sum(10,20) ;
b := sumstr("тест"," удачный") ;
← →
TakTak (2006-09-27 15:47) [10]из файла funct.txt она узнает о подключаемых функциях, грузит их из funct.dll и вызывает их по требованию, а требование определает исполняемый файл
← →
clickmaker © (2006-09-27 15:51) [11]
> [9] TakTak (27.09.06 15:45)
хм... ну что я могу сказать.... Если формат этого файла компановки может быть только таким, то остается только его парсить.
К примеру, получил имя функции
fn := GetProcAddress(hLib, FuncName);
получил параметры и дальше
asm
push param1
...
call fn
end;
что-то типа
← →
TakTak (2006-09-27 15:56) [12]парсинг и прочее - всё готово.
вот вот !!! на счет азма можно чуть подробнее ???? плз !!!
← →
clickmaker © (2006-09-27 16:03) [13]
> чуть подробнее ???? плз !!!
куда уж подробнее
asm // начало ассамблерного кода
push param1 // заталкиваем в стек параметр
call fn // вызываем функцию по ее адресу
end;
тут нужно еще учесть, как функция объявлена в DLL - stdcall, cdecl. От этого зависит очередность параметров в стеке
← →
TakTak (2006-09-27 16:06) [14]а выделение памяти, заполнение стека ..... вот так просто push и всё ?
← →
clickmaker © (2006-09-27 16:10) [15]
> а выделение памяти, заполнение стека
если у тебя параметры там размером не более 32-бит, то достаточно push paramValue
если больше, то ты должен передать адрес, по которому лежит значение
← →
TakTak (2006-09-27 16:19) [16]спасибо, пошел разбираться !
← →
guav © (2006-09-27 16:27) [17]> [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;
← →
zamtmn © (2006-09-27 19:24) [18]>>Для cdecl думаю можно обойтись без asm и достаточно одного объявления на все случаи жизни.
>> I := F(1, 2, "Hello");
в comtiletime о (1, 2, "Hello") никто ниче не знает, для всех соглашений о вызовах стек придется формировать runtime
← →
zamtmn © (2006-09-27 19:33) [19]function Sum (a : real; b : real) : real ;
такой вид функций обязателен? это придется почтишто компилятор написать:)
можно всё сильно упростит создав свой стек параметров
будешь иметь унифицированный вызов всех процедур
procedure Sum (p:pstack;ctackheap:integer);
в длл выбираешь из p^ два значения, суммируешь и помещаешь обратно, наподобии как FPU работает
Страницы: 1 вся ветка
Текущий архив: 2006.10.15;
Скачать: CL | DM;
Память: 0.48 MB
Время: 0.046 c