Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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.51 MB
Время: 0.034 c
15-1158797255
Потенциальный кандидат наук
2006-09-21 04:07
2006.10.15
Ктонить защищал кандидатскую? Сколько нужно средств...


15-1158922242
VitV
2006-09-22 14:50
2006.10.15
Необходимые библиотеки для VB6


1-1157096899
NiGGa
2006-09-01 11:48
2006.10.15
Переход D5 -> D7


5-1140943637
Reset
2006-02-26 11:47
2006.10.15
Default - значения свойств


3-1155639526
2ded
2006-08-15 14:58
2006.10.15
Сохранение результата запроса на др. машине