![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
работа с DLL и тем что внутри. [D6, WinXP]
newver © (2004-10-07 07:48:00)предположим есть DLL в которой имеется набор экспортируемых функций.
1. как узнать, какие там есть функции (имена)
2. их параметры (количество, тип)
или
есть текстовый файл в котором прописаны все эти функции и параметры.
как мне подключить их (програмно разумеется, считывая из файла) и выполнить?
т.е. как обратится к функции, если её имя и параметры содержатся в "строке" (имет вид строки) ?
newver (2004-10-14 09:18:00) [1]с вызовом проблем нет, а вот с её параметрами .... кажется имеются ...
KSergey (2004-10-14 09:14:00) [2]Вот и я так понял, что до начала выполнения проги ему не известны прототипы ф-ций.
Тогда надо распарсить файл и в соотв с указанным типом нашпиговать стек параметрами и вызвать ф-цию из DLL.
newver (2004-10-14 08:37:00) [3]блин проблемма всё осталась той же ...
Есть функция в которой из DLL подключается некая Summ. Получаем адрес по которому она сидит и дальше, как мне подсказали, можно воспользоваться asm-ом для указания всех параметров (для ф-ий stdcall). А с этим туго ... может найдётся умелец, который поможет мне запихать все параметры в стек??? Вот пример:
procedure Test();
var
p : pointer ;
DLLHandle : THandle ;
begin
DLLHandle := LoadLibrary('modul.dll');
if DLLHandle <> 0 then
begin
p := GetProcAddress(DLLHandle , 'Summ') ;
if p<>nil then
begin
>>asm
>>
>>
>>end;
end
else
ShowMessage('false');
end
else
ShowMessage('false');
end;
Digitman (2004-10-07 12:23:00) [4]
> newver
разумеется, массив и его эл-ты в этом случае д.б. объявлен и заполнент примерно так :
type
TProcCallDesc = packed record
Procname: String;
Params: array of Variant;
end;
TProcCalls = array of TProcCallDesc;
...
var
ProcCalls: TProcCalls;
..
//заполнение i-го элемента на этапе разбора скрипта
ProcCalls[i].ProcName := 'print'
ProcCalls[i].Params := VarArrayOf(['1', '2', '3']);
newver (2004-10-07 12:19:00) [5]:))
спасибо.
попробую, но всё равно придётся завтра с этим вопросом к преподу идти, авсоь не ообзлиться. Посмотрим что оон мне скажет.
АлексейК (2004-10-07 12:17:00) [6]- Доктор, у меня что-то болит вот тут.
- Сейчас я вам выпишу какие-то таблетки.
Reindeer Moss Eater (2004-10-07 12:08:00) [7]есть программа (которую надо написать) и текстовый файл с DLL.
А где слово "лопата"?
Bes (2004-10-07 12:03:00) [8]аа..ну если если типы процедур(кол-во параметров, типы параметров) уже известны тогда то, что я привел лишнее... потому что там я пытал как бы унифицировать процедуры и работу с ними =)
Digitman (2004-10-07 11:53:00) [9]
> newver (07.10.04 11:11) [16]
ну вот это совсем другой коленкор !
для всех таких деклараций в текст.файле ты должен сделать соотв.декларации в своем приложении
конкретно для данного фрагмента можно описать эти ф-ции так :
type
float = Double; //пусть некий абстрактный float-тип интерпретируется как конкретный double-тип
function Sum (a,b : float) : float; external 'mydll.dll';
function VectorSum (a,b,c : float) : float; stdcall; external 'mydll.dll';
procedure Prnt (a : variant) ; external 'mydll.dll';
function sq (a : integer) : integer ; external 'mydll.dll';
теперрь ты можешь смело брать из своего массива имя ф-ции, сопоставить его с тем именем, что ты объявил в Паскаль-декларации, и вызывать эту ф-цию с требуемыми параметрами
например,
if CompareText(myarr[i].procname, 'sum') = 0 then
MyFloatResult := sum(myarr[i].Params[0], myarr[i].Params[1])
elseif CompareText(myarr[i].procname, 'vectorsum') = 0 then
MyFloatResult := vectorsum(myarr[i].Params[0], myarr[i].Params[1], myarr[i].Params[2])
elseif CompareText(myarr[i].procname, 'print') = 0 then
Prnt(myarr[i].Params[0])
elseif CompareText(myarr[i].procname, 'sq') = 0 then
MyIntResult := sq(myarr[i].Params[0])
elseif .. и т.д. и т.п.
Bes (2004-10-07 11:51:00) [10]2 newver так как ты хочешь сделать врядли получится... потому что тебе надо объявлять процедуру, т.е. создавать на нее указатель,а потом присваивать этому указателю , указатель на процедуру из DLL
(@somproc:=getprocaddree(dllhandle,'procname');)
единственное что мне приходит на ум... это сделать передачу в процедуру не значения а указатель ака поинтер,а уж сама процедура в длл будет пробовать его на вкус,че там получилось...
типа создать записить и передавать....
вот примерный сорц...
//структура
TRec=record
//параметры
fa,fb,fc:float;
va:variant;
ia:integer;
//возвращаемые значения
resf:float;
resi:integer;
end;
Prec=^TRec;
var
Proc:array of procedure(P:Prec); //динамический массив процедур
ProcList:TStringList; //имена процедур (загружены из файла)
procedure LoadNames;
var
i:integer;
begin
if Not Assigned(ProcList) then ProcList:=TStringList.create;
ProcList.loadfromfile('proclist.txt');
SetLength(proc,ProcList.count);
end;
procedure LoadDLL;
var
i:integer;
begin
hLib := LoadLibrary('dllname.dll');
if hLib <> 0 then
begin
for i:=0 to ProcList.count-1 do begin
@Proc[i] := GetProcAddress(pchar(ProcList.Strings[i]);
end;
т.е. потом просто если надо вызвать допустим функцию print
var
P:PRec;
Getmem(p,sizeof(Trec));
try
i:=procList.indexof('print');
p^.fa:=1.23;
p^.fb:=0.5;
Proc[i](p);
showmessage(inttostr(p^.resi));
finally
freemem(p);
end;
end;
вообщем так, не бейте особо мож что-то и упустил ..не тестировал здесь писал....
newver (2004-10-07 11:11:00) [11]function Sum (a,b : float) : float;
function VectorSum (a,b,c : float) : float; stdcall;
procedure Prnt (a : variant) ;
function sq (a : integer) : integer ;
Digitman (2004-10-07 10:20:00) [12]
> кол-во параметров не ограничено, т.е. не указано, оно варьируемо.
> Как с этим быть?
> DLL собиралась на дельфях
никак не стыкуются эти два утверждения.
Паскаль не имеет механизма передачи в п/программу произвольного числа параметров
> В текстовике всё есть
так я и попросил тебя привести фрагмент такого описания !
т.е. привести пример прототипалюбой ф-ции, так как он выглядит в "текстовике" ..
а то что ты привел - это не прототип, это уже скрипт, т.е. описание фактическоговызова конкретной процедуры с конкретными параметрами ..
newver (2004-10-07 10:10:00) [13]откуда у тебя вдруг взялись типы ф-ций и типы параметров ? ты же сказал, что они тебе неизвестны ? >> сори, видать опять не правильно написал. В текстовике всё есть.
// DLL собиралась на дельфях 5х (другого у нас нет)//
newver (2004-10-07 10:06:00) [14]откуда у тебя вдруг взялись типы ф-ций и типы параметров ? >> описаны в текстовике
newver (2004-10-07 10:05:00) [15]плохо дано >> в том то и есть дело, что всё дано. только вот меня смущает следующее:
>>type
>> TSomeExpProc = procedure(Param1, Param2, Param3: PChar);
>>[somecallingconvention;]
кол-во параметров не ограничено, т.е. не указано, оно варьируемо. Как с этим быть?
>>П7 Двойка тебе, короче, за это задание!
да ... согласен с тобой, но если не сделаю, то ... надо всё таки а то вылечу.
Digitman (2004-10-07 10:04:00) [16]
> После обработки текстового файла у меня получается массив
> в котором содержатся имена файнкций их типы и передаваемые
> параметры
откуда у тебя вдруг взялись типы ф-ций и типы параметров ? ты же сказал, что они тебе неизвестны ?
П7 (2004-10-07 09:51:00) [17]В общем видно, что задание этот студент понял плохо. Т.к. лекции посещал нерегулярно. Двойка тебе, короче, за это задание! ВотЪ! (:
Digitman (2004-10-07 09:43:00) [18]
> Дано: DLL
плохо дано
если уж "дано", то и прототипы эксп.т.входа тоже должны быть "даны" .. вместе с файлом ДЛЛ .. иначе лаб.работа должна была включать в т.ч. и задание по изучению "внутренностей" ДЛЛ при помощи дизассемблирования и анализа листинга
Digitman (2004-10-07 09:38:00) [19]type
TSomeExpProc = procedure(Param1, Param2, Param3: PChar); [somecallingconvention;]
var
SomeExpProc: TSomeExpProc;
hLib := LoadLibrary('MyDll.dll');
if hLib <> 0 then
begin
SomeExpProc := GetProcAddress('print');
if Assigned(@SomeExpProc) then
SomeExpProc('1', '2', '3');
end;
П7 (2004-10-07 09:35:00) [20]Поищи в Сети - "скриптовые языки программирования", "парсинг текста", "методы работы с DLL".
Ты расскажи лучше, зачем тебе это нужно, наверняка есть более элегантные способы решения твоей ОСНОВНОЙ проблемы, нежели то, что придумал.