-
Здравствуйте. Хочется узнать, есть ли способ получить список всех export'нутых функций и процедур из DLL и списком параметров к ним с указанием типа параметра + тип результата функции. Например:
type
TDLLFunctionParam = record
Name: String;
pType: String;
end;
TDLLFunctionParams = array of TDLLFunctionParam;
TDLLFunction = record
Name: String;
Params: TDLLFunctionParams;
Result: TDLLFunctionParam;
end;
TDLLFunctions = array of TDLLFunction;
var
h: HWND;
fs: TDLLFunctions;
begin
h := LoadLibrary('C:\mylib.dll');
fs := getLibraryFunctions(h);
end;
и затем вызвать любую функцию и получить результат:
var
h: HWND;
fs: TDLLFunctions;
f: TDLLFunction;
s: String;
begin
h := LoadLibrary('C:\mylib.dll');
fs := getLibraryFunctions(h);
f := fs[0];
s := callLibraryFunction(h, f, ['a', '1', '1.2']);
end;
то есть я передаю handle библиотеки, функцию и массив строковых параметров, получаю строковой результат в SИли нужно заранее знать имена всех функций и четко предопределять параметры? Вызывая GetProcAddress(Module: THandle; ProcName: PChar);
-
> Или нужно заранее знать имена всех функций и четко предопределять > параметры?
да
-
А если я заведомо знаю имена функций и кол-во параметров, функцию braryFunction(h, f, ['a', '1', '1.2']); можно будет использовать?.. Или я пролетел вообще?)
-
> Vidog © (30.11.10 20:34) [2]
> А если я заведомо знаю имена функций и кол-во параметров, > функцию braryFunction(h, f, ['a', '1', '1.2']); можно будет > использовать?.. Или я пролетел вообще?)
А с какого вдруг пуркуа длл?
See also: varargs directive.
-- Regards, LVT.
-
> А если я заведомо знаю имена функций и кол-во параметров, > функцию braryFunction(h, f, ['a', '1', '1.2']); можно будет > использовать?.. Или я пролетел вообще?)
можно
-
2 Игорь Шевченко >>можно
подскажите, пожалуйста.
-
> Vidog © (01.12.10 22:02) [5] > подскажите, пожалуйста.
Готов подсказать, если пользование длл обоснованно.
-- Regards, LVT.
-
> подскажите, пожалуйста.
что подсказать ?
-
> что подсказать ?
каким образом можно реализовать вот это: s := callLibraryFunction(h, f, ['a', '1', '1.2']); из части кода. желательно на WinAPI. Куда копать, что почитать :)
-
> из части кода. желательно на WinAPI. Куда копать, что почитать > :) http://www.delphi-jedi.org раздел API Tranlsation например почитать
-
>>dlopen я в ту сторону копаю?)
-
-
function test(a, b, c: String): String;
begin
Result := '[' + a + ']' + '[' + b + ']' + '[' + c + ']';
end;
exports test;
Вот такая в DLL тестовая функция с 3мя параметрами.
var
modl: TModuleHandle;
P: Pointer;
S: String;
begin
LoadModule(modl, 'Project1.dll');
P := GetModuleSymbol(modl, 'test');
S := 'qwe-qwe-qwe';
WriteModuleData(modl, 'test', S, sizeOf(S));
end;
насколько я понял, передать данные можно через WriteModuleData, а прочитать потом через ReadModuleData. Так вот.. Каким образом передать 3 параметра? Выполнить функцию 3 раза? Каждый раз записывая параметр. Или я вообще не туда полез...
-
> LoadModule
> WriteModuleData
Это вообще из какой оперы ?
-
> Это вообще из какой оперы ?
moduleloader.pas
=/ что-то у меня ничего не получается...
-
> Vidog © (03.12.10 09:48) [14]
Что ты испод нас хочешь?
-- Regards, LVT.
-
> Vidog © (03.12.10 09:48) [14] > > > > Это вообще из какой оперы ? > > > moduleloader.pas >
Какой еще нахрен "moduleloader.pas" ? Нет такого юнита в составе штатных дельфийских юнитов. По кр.мере - в Д7.
-
> Сергей М. © (03.12.10 20:49) [16]
> Какой еще нахрен "moduleloader.pas" ?
М.б. by JEDI?
Хотя, конечно, проще отрубить ему голову.
-- Regards, LVT.
-
> Какой еще нахрен "moduleloader.pas" ?
из JEDI библиотеки..
Мужики, ну спасайте) Дайте хоть ссылочку на пример или какие использовать модули / функции.
-
> Vidog © (05.12.10 22:23) [18]
Посмотрел.
Этот самый moduleoader не имеет никакого отношения к тому что тебе нужно.
А то что тебе нужно, т.е.
> спискоr параметров к ним с указанием типа параметра + тип результата функции
гарантированно на 100% в ран-тайм можно получить только в отдельных частных случаях. В прочих случаях, не относящихся к этим самым "частным", задача в ран-тайм практически не решаема.
-
> function test(a, b, c: String): String; > begin > Result := '[' + a + ']' + '[' + b + ']' + '[' + c + ']'; > end; > exports test;
а конкретно в таком случае? без определения этой функции и получения ее адреса с последующим вызовом, можно передать ей параметры "на лету" и забрать результат?
-
> а конкретно в таком случае?
<offtop> Твой вопрос сильно смахивает на задачу/вопрос XYZ http://www.gunsmoker.ru/2008/10/x-y-z.html</offtop> Сам подумай кому нужно ломать голову над некой тестовой функцией, которая не имеет никакого смысла для отвечающих? > Мужики, ну спасайте
Пока не озвучишь свою реальную задачу, на реальную помощь не надейся.
-
лучше отрубить голову.
-
> а конкретно в таком случае?
А чем этот "конкретно такой случай" отличается от "неконкретно хз какого случая" ?
-
rundll как-то работает. Загружает DLL, ищет в ней функцию с указанным именем, преобразует параметры из строк в числа или в строки, передает эти параметры и вызывает нужную функцию.
Автору наверное надо что-то похожее.
-
> Игорь Шевченко © (06.12.10 23:14) [24] > > rundll как-то работает
Вот-вот. Как rundl работает? "Загружает DLL, ищет в ней функцию с указанным именем, преобразует параметры из строк в числа или в строки, передает эти параметры и вызывает нужную функцию". Не верю.
-
+1 А если Dll C'ишная...? Это бред. ))
-
> Германн © (07.12.10 04:08) [25]
> Вот-вот. Как rundl работает?
Чему ты не веришь? Функции, которые она вызывает имеют прототип:
procedure X( wnd: HWND; hinst: THandle; CmdLine: PChar; nCmdShow: Longint); stdcall; Х должна быть в экспортах.
А rundll, получив строку, должна выделить (и преобразовать) 3 числа и строку параметров.
-- Regards, LVT.
-
> Автору наверное надо что-то похожее
Было бы "надо" - он бы сказал. А он, похоже, даже своё "надо" в лицо не знает. Но при этом ему "хочется". А что ему "хочется" - это он уточнять не намерен)
-
> Сергей М. © (07.12.10 19:33) [28]
> ему "хочется". А что ему "хочется" - это он уточнять не > намерен)
Ему хочется странного, потому древние китайцы ему голову и постановили элиминировать.
-- Regards, LVT.
-
> Leonid Troyanovsky © (07.12.10 22:56) [29]
Кошмар, конечно, но.. с древнекитайскими традициями вряд ли поспоришь) .. особливо здесь, в Мастерской)
-
> Сергей М. © (07.12.10 23:29) [30]
> Кошмар, конечно, но.. с древнекитайскими традициями вряд > ли поспоришь) .. особливо здесь, в Мастерской)
А в Детской рискнешь? :)
-- Regards, LVT.
-
> Leonid Troyanovsky © (07.12.10 23:40) [31]
> в Детской рискнешь? :)
В детской тем паче не рискну)
-
> Leonid Troyanovsky © (07.12.10 16:08) [27] > > > > Германн © (07.12.10 04:08) [25] > > > Вот-вот. Как rundl работает? > > Чему ты не веришь? > Функции, которые она вызывает имеют прототип: >
Не верю в реальность вызова произвольной функции из произвольной библиотеки а-ля rundll. А все остальное - к автору вопроса. С учётом Германн © (06.12.10 00:26) [21]
-
> Германн © (08.12.10 02:01) [33]
> Не верю в реальность вызова произвольной функции из произвольной > библиотеки а-ля rundll.
Произвольной - я тоже не верю. http://support.microsoft.com/kb/164787Про 3 числа я не совсем верно сказал, только параметры, sorry. -- Regards, LVT.
-
> [24] > rundll как-то работает. Загружает DLL, ищет в ней функцию > с указанным именем, преобразует параметры из строк в числа > или в строки, передает эти параметры и вызывает нужную функцию. > Автору наверное надо что-то похожее.
Да. именно это и нужно.
Я пытаюсь создать так называемую систему "плагинов" к приложению. Как например модули DLL для php. Все функции экспортнуты внутри DLL, число параметров, допустим, будет известно, имена функций тоже.
плагин к lister'у тотал-коммандера умеет находить в любой библиотеке функции, которые были объявлены на export. И даже запускать процедуры (без параметров).
Поэтому заранее предопределить вызовы внутри приложения не получится. Они переменны и в каждой DLL будут уникальны.
-
> Как например модули DLL для php
Те же самые "модули DLL для php" - вполне документированная спецификация и технология, безо всякого бардака типа "на вот тебе модуль, в нем заранее неопределенная хуча экспортнутых точек входа, а их параметры выковыривай сам если тебе приспичило ".
Так что это сравнение - в топку.
-
> Все функции экспортнуты внутри DLL, число параметров, допустим, > будет известно, имена функций тоже.
> Поэтому заранее предопределить вызовы внутри приложения > не получится. Они переменны и в каждой DLL будут уникальны.
Если разработчику приложения заранее известны имена функций в dll и их параметры, то ничто не мешает стандартному вызову этих функций в приложении. Если нет, то как их вообще можно разумно вызвать? Даже если приложению сказать что есть dll-имярек, в которой есть функция-имярек, у которой N параметров такого-то типа. Вызвать-то её теоретически можно, но вот какие значения параметров при этом передавать, если про смысл этих параметров приложение заранее не знает!
-
Забыл упомянуть что такая же неопределенность существует и для результата функции вызванной из библиотеки. С той лишь разницей, что "обычные" плагины основной результат, как правило, "обрабатывают сами". А во внешнее приложение только сообщают об ошибке, если таковая случится.
P.S. Эта мода на плагины уже достала. Не на форуме, а от заказчиков.
-
Удалено модератором
-
Удалено модератором
-
По-моему, автору вот это надо: http://ru.wikipedia.org/wiki/DLL program Example;
var result: Double;
LibHandle: Hmodule;
AddNumbers: function(a, b: Double): Double;
begin
LibHandle := LoadLibrary('Example.dll'); if LibHandle <> 0 then
begin
@AddNumbers := GetProcAddress(LibHandle, 'AddNumbers'); if @AddNumbers <> nil then
begin
result := AddNumbers(1, 2); Writeln('The result was: ', result);
end;
FreeLibrary(LibHandle); end;
end.
-
> Вот-вот. Как rundl работает?
push push ... push call ?
-
> По-моему, автору вот это надо:
Как раз таки нет. Я же писал, что без предопределения функции. Вызов динамический.
-
> Как раз таки нет. Я же писал, что без предопределения функции. > Вызов динамический.
Вот Незнайка (Не прими на свой счёт. Имеется в виду персонаж известного произведения Н. Носова :) тоже хотел иметь волшебную палочку. Он её и получил после совершения трех хороших поступков. Но что было далее? Прочитай. Полезно будет.
-
> Германн © (17.12.10 01:53) [44]
> Но что было далее?
Надругался над Дюймовочкой, ака Жаба? :)
-- Regards, LVT.
-
> Как раз таки нет. Я же писал, что без предопределения функции. > Вызов динамический.
Так ведь
Vidog © (30.11.10 20:34) [2] > А если я заведомо знаю ... кол-во параметров...
Что тогда подразумевается под "знанием", если не предопределение типа функции?
-
> Leonid Troyanovsky © (17.12.10 19:25) [45] > > > > Германн © (17.12.10 01:53) [44] > > > Но что было далее? > >
Тебе тоже стоит прочитать. :) Ибо наломал Незнайка, а исправлять-то придётся волшебнику! :)
-
> Что тогда подразумевается под "знанием", если не предопределение > типа функции?
Просто физически известно, что функция называется Sum и у нее 2 параметра: A и B
без определения функции Sum, нужно подключиться к библиотеке, найти адрес функции, послать ей массив из 2х элементов и получить результат.
-
> послать ей массив
Обязательно массив? Если нет, то не очень понятно, чем приведённый пример не устраивает. var AddNumbers: function(a, b: Double): Double; - это не определение функции, это определение переменной, имеющий тип функции с двумя параметрами типа Double. А далее, собственно, всё, как Вы и говорите - загружаем библиотеку, находим в ней адрес функции и вызываем. А как иначе вы расскажете компилятору, то, что Вам > физически известно? Если не нравится - пишите на ассемблере, но исполнимый код-то в результате всё равно получится такой же.
-
> известно, что функция называется Sum и у нее 2 параметра: > A и B > > без определения функции Sum, нужно подключиться к библиотеке, > найти адрес функции, послать ей массив из 2х элементов > и получить результат
Ожидаемый результат ты не получишь, с вероятностью ориентировочно фифти-фифти) Потому что знания имени точки входа, кол-ва параметров и даже их типов НЕдостаточно для успешной эксплуатации функции. Как минимум нужно достоверно знать еще и соглашение о вызове.
-
> clickmaker © (13.12.10 19:14) [42] > > Вот-вот. Как rundl работает?pushpush...pushcall ?
Господин, Вы, кажется, забыли про стандарты вызова.. Даже это будет не так-то и просто..
|