Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.10.31;
Скачать: [xml.tar.bz2];

Вниз

работа с DLL и тем что внутри.   Найти похожие ветки 

 
newver   (2004-10-07 07:48) [0]

предположим есть DLL в которой имеется набор экспортируемых функций.
1. как узнать, какие там есть функции (имена)
2. их параметры (количество, тип)
или
есть текстовый файл в котором прописаны все эти функции и параметры.
как мне подключить их (програмно разумеется, считывая из файла) и выполнить?
т.е. как обратится к функции, если её имя и параметры содержатся в "строке" (имет вид строки) ?


 
Digitman ©   (2004-10-07 08:03) [1]


> есть текстовый файл в котором прописаны все эти функции
> и параметры.


как-то не вяжется это с вопросами 1 и 2
если есть описание, то что там узнавать-то ?

приведи фрагмент описания какой-либо ф-ции и ее параметров из этого текст.файла ..


 
newver   (2004-10-07 08:31) [2]

это два разных варианта.
объясняю по другому:

есть программа (которую надо написать) и текстовый файл с DLL. внутри текстового файла описана функция которая есть в DLL. Задача программы (которую надо написать), открыть этот текстовый файл, считать функцию, распознать, где есть имя а где параметр (это совсем дургое и пока не нужно) и выполнить эту функцию (основная задача). Содержимое файла может меняться!!! а программа должна уметь находить указанную функцию в текстовом файле, сама определять какие там у него параметры и выполнять функцию.


 
newver   (2004-10-07 08:35) [3]

другой пример:
funct_name := "print" ;
param := "("1","2","3");

ОК. как мне дельфи компилятору сказать что funct_name это не строка а имя функции, а param  это её парамтры???? А потом вызвать эту функцию из DLL.


 
Digitman ©   (2004-10-07 08:54) [4]

так ведь это совсем не то что ты описал изначально !

в текстовом файле у тебя прописаны не описания ф-ций и их форм.параметров, а порядок вызова тех или иных ф-ций с конкретными значениями факт.параметров ... это своего рода скрипт, который тебе требуется интерпретировать средствами будущей своей программы

в такой ситуации, когда прототипы ф-ций (т.е. детальные их описания) отсутствуют, без дизассемблера не обойтись ... только дизассемблировав ДЛЛ и проанализировав полученный листинг можно с достаточной вероятностью успеха получить инф-цию о :

- точных именах ф-ций/процедур (в принципе эта инф-ция м.б. получена и иным удобным способом, например, средствами утилит dump.exe или depends.exe)

- реальных языковых соглашениях об их вызове

- количестве, типе и порядке передачи параметров для каждой из эксп.точек входа

без получения такой точной инф-ции двигаться далее в разработке своего скрипт-интерпретатора бессмысленно


 
newver   (2004-10-07 09:29) [5]

предположим, что имена, возвращаемый тип, известны, параметры (количество и их тип) тоже, как тогда можно подключить???
т.е. в текстовом файле идёт полное описание всех функций и их параметров.


 
newver   (2004-10-07 09:33) [6]

это не глобальная какая-то програ, а обычная лаб. раб. :)
извиняюсь за непонятность в объяснении.

изначально Дано: DLL и текстовый файл в котором описаны (досканально) все функции (тип, параметры, типа параметров и т.д.).
 Распознать  "ху ис ху" в этом текстовом файле получилось, а выполнить не могу, ума не хватает. :(
 После обработки текстового файла у меня получается массив в котором содержатся имена файнкций их типы и передаваемые параметры, а дальше как ??? как вызвать и выполнить её динамически?


 
П7   (2004-10-07 09:35) [7]

Поищи в Сети - "скриптовые языки программирования", "парсинг текста", "методы работы с DLL".

Ты расскажи лучше, зачем тебе это нужно, наверняка есть более элегантные способы решения твоей ОСНОВНОЙ проблемы, нежели то, что придумал.


 
Digitman ©   (2004-10-07 09:38) [8]

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;


 
Digitman ©   (2004-10-07 09:43) [9]


> Дано: DLL


плохо дано
если уж "дано", то и прототипы эксп.т.входа тоже должны быть "даны" .. вместе с файлом ДЛЛ .. иначе лаб.работа должна была включать в т.ч. и задание по изучению "внутренностей" ДЛЛ при помощи дизассемблирования и анализа листинга


 
П7   (2004-10-07 09:51) [10]

В общем видно, что задание этот студент понял плохо. Т.к. лекции посещал нерегулярно. Двойка тебе, короче, за это задание! ВотЪ! (:


 
Digitman ©   (2004-10-07 10:04) [11]


> После обработки текстового файла у меня получается массив
> в котором содержатся имена файнкций их типы и передаваемые
> параметры


откуда у тебя вдруг взялись типы ф-ций и типы параметров ? ты же сказал, что они тебе неизвестны ?


 
newver   (2004-10-07 10:05) [12]

плохо дано >> в том то и есть дело, что всё дано. только вот меня смущает следующее:

>>type
>> TSomeExpProc = procedure(Param1, Param2, Param3: PChar);
>>[somecallingconvention;]

кол-во параметров не ограничено, т.е. не указано, оно варьируемо. Как с этим быть?
>>П7 Двойка тебе, короче, за это задание!
 да ... согласен с тобой, но если не сделаю, то ... надо всё таки а то вылечу.


 
newver   (2004-10-07 10:06) [13]

откуда у тебя вдруг взялись типы ф-ций и типы параметров ? >> описаны в текстовике


 
newver   (2004-10-07 10:10) [14]

откуда у тебя вдруг взялись типы ф-ций и типы параметров ? ты же сказал, что они тебе неизвестны ? >> сори, видать опять не правильно написал. В текстовике всё есть.
//  DLL собиралась на дельфях 5х (другого у нас нет)//


 
Digitman ©   (2004-10-07 10:20) [15]


> кол-во параметров не ограничено, т.е. не указано, оно варьируемо.
> Как с этим быть?



> DLL собиралась на дельфях


никак не стыкуются эти два утверждения.

Паскаль не имеет механизма передачи в п/программу произвольного числа параметров


> В текстовике всё есть


так я и попросил тебя привести фрагмент такого описания !
т.е. привести пример прототипа любой ф-ции, так как он  выглядит в "текстовике" ..

а то что ты привел - это не прототип, это уже скрипт, т.е. описание фактического вызова конкретной процедуры с конкретными параметрами ..


 
newver   (2004-10-07 11:11) [16]

function Sum (a,b : float) : float;
function VectorSum (a,b,c : float) : float; stdcall;
procedure Prnt (a : variant) ;
function sq (a : integer) : integer ;


 
Bes ©   (2004-10-07 11:51) [17]

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;

вообщем так, не бейте особо мож что-то и упустил ..не тестировал здесь писал....



 
Digitman ©   (2004-10-07 11:53) [18]


> 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 12:03) [19]

аа..ну если  если типы процедур(кол-во параметров, типы параметров) уже известны тогда  то, что я привел лишнее... потому что там я пытал как бы унифицировать процедуры и работу с ними =)


 
Reindeer Moss Eater ©   (2004-10-07 12:08) [20]

есть программа (которую надо написать) и текстовый файл с DLL.

А где слово "лопата"?


 
АлексейК   (2004-10-07 12:17) [21]

- Доктор, у меня что-то болит вот тут.
- Сейчас я вам выпишу какие-то таблетки.


 
newver   (2004-10-07 12:19) [22]

:))
спасибо.
попробую, но всё равно придётся завтра с этим вопросом к преподу идти, авсоь не ообзлиться. Посмотрим что оон мне скажет.


 
Digitman ©   (2004-10-07 12:23) [23]


> 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-14 08:37) [24]

блин проблемма всё осталась той же ...
Есть функция в которой из 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;


 
KSergey ©   (2004-10-14 09:14) [25]

Вот и я так понял, что до начала выполнения проги ему не известны прототипы ф-ций.
Тогда надо распарсить файл и в соотв с указанным типом нашпиговать стек параметрами и вызвать ф-цию из DLL.


 
newver   (2004-10-14 09:18) [26]

с вызовом проблем нет, а вот с её параметрами .... кажется имеются ...



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2004.10.31;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.03 c
6-1093279257
Johnny Raw
2004-08-23 20:40
2004.10.31
вопрос по поводу IdHTTP1.Response.LastModified


1-1098072922
md5 hash
2004-10-18 08:15
2004.10.31
Объекты в StringGrid


1-1098000661
Ralf
2004-10-17 12:11
2004.10.31
Текстовые редакторы


14-1097495259
KilkennyCat
2004-10-11 15:47
2004.10.31
Зачем у харддиска резина?


3-1096553190
stud
2004-09-30 18:06
2004.10.31
рекурсия в запросе





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский