Форум: "Система";
Текущий архив: 2004.05.16;
Скачать: [xml.tar.bz2];
ВнизИмпорт функции из .exe Найти похожие ветки
← →
Fiend © (2004-03-31 15:25) [0]Здравствуйте Уважаемые!!!
Есть у меня с коллегой общий проект. В нём есть утилита для автоматического обновления. Естественно .exe файл.
Так вот соавтор попросил сделать функцию в этой утилите, с помощью которой можно было запустить "процесс" обновления. Выбрали вариант с экспортом функции потому, что Требуется передать несколько параметров, которые передавать через командную строку не есть гуд.
Функцию сделал, но вот незадача, как только exe загружен LoadLibrary и указатель на ф-цию получен от GetProcAddress, мы ее ессесно вызываем и в отладчике замечаем ужасную картину: на первой же команде происходит AV. Где порыть ума не приложу.
это экспортируемое:
type
TScript = record
Size: WORD;
PScript: PChar;
end;
PScript = ^TScript;
function ExternalCall(Script: PScript): boolean; stdcall;
begin
MainForm:= TMainForm.Create(Application);
MainForm.UpdateNow(Script);
MainForm.ShowModal;
Result:= MainForm.LoadResult=1;
MainForm.Free;
end;
exports ExternalCall;
а это уже загрузка и выполнение:
type
TExternalCall = function (Script: PScript): boolean; stdcall;
var hLibrary: THandle;
fExternalCall: TExternalCall;
Script: TScript;
Result: boolean;
begin
hLibrary:= LoadLibrary("UpdWizard.exe");
@fExternalCall:= GetProcAddress(hLibrary, "ExternalCall");
Script.PScript:= AllocMem(1000);
StrPCopy(Script.PScript, "/ok/cgi/news.exe?getupdscr&stylea");
Script.Size:= StrLen(Script.PScript);
Result:= fExternalCall(@Script);
FreeLibrary(hLibrary);
FreeMem(Script.PScript, 1000);
end.
Помогите пожалуйста, хотя бы обсуждением.
← →
Cobalt © (2004-03-31 15:47) [1]ГЫЫЫЫ :))))
А Application кто будет инициализировать????
Это же объект - в ЕХЕ-ке загруженном, а не в вашем, вызывающем.
Общая рекомендация - отделяйте "бизнес-логику" (деловую логику) от интерфейса!!!
← →
Fiend © (2004-03-31 15:53) [2]Я бы не стал так смеяться.
Потому что даже если первой коммандой поставить тривиальнейший Beep(), то всё равно ошибка прямо на нём. Да и в конце концов можно создавать форму указывая nil.
Так что дело не в этом.
← →
Digitman © (2004-03-31 16:14) [3]
> Fiend
не смотря на ржание Cobalt"а аки жеребца молодого, он прав
прав в том, что загрузка и/или инициализация требуемых модулей (в т.ч. и в 1-ю очередь - VCL-модулей) происходит при передаче системой управления на точку входа в exe .. что не происходит при LoadLibrary()
← →
Fiend © (2004-03-31 16:18) [4]Что вы предлагаете сделать?
Application.Initialize первой же строкой?
Делал, результат тот же.
← →
Digitman © (2004-03-31 16:22) [5]попробуй-ка реализовать и экспортировать в exe простую ф-цию
const SomeStr: PChar = "Hello, World !";
function GetSomeString: PChar;
begin
Result := SomeStr;
end;
и вызвать эту ф-цию после LoadLibrary() и GetProcAddress()
ShowMessage(String(GetSomeString));
и все пройдет на ура !
почему ? да потому что тело импортируемой ф-ции не содержит ни единого обращения ни к одному из внешних и/или неявно инициализируемых (в ходе старта exe-процесса) модулей, т.е. никак не зависит от какого-либо дополнительного/вспомогательного кода/данных ... иными словами - импортируемая ф-ция реализована в теле exe-модуля как 100%-но самодостаточная
← →
Digitman © (2004-03-31 16:26) [6]
> Fiend
предлагаю не заморачиваться этой идеей, если она хоть как-то использует внутри экспортируемой ф-ции VCL
все, что тебе нужно, вполне реализуемо и иными способами, и манипуляция с ком.строкой - не самый худший способ ... просто продумать следует его
← →
Digitman © (2004-03-31 16:28) [7]
> Application.Initialize первой же строкой?
> Делал, результат тот же.
а кто и когда создал объект Application ?
никто и никогда !
вот тебе и ответ
← →
Fiend © (2004-03-31 16:32) [8]Урезал функции до предела
это экспортируем
function ExternalCall{(Script: PScript)}: boolean; stdcall;
begin
ShowMessage("asdasdf");
{ assert(Application=nil, "sux");
MainForm:= TMainForm.Create(nil);
MainForm.UpdateNow(Script);
MainForm.ShowModal;
Result:= MainForm.LoadResult=1;
MainForm.Free;}
end;
это импортируем
type
TExternalCall = function {(Script: PScript)}: boolean; stdcall;
Загружаем, получаем адрес, и вызываем:
AV.
Вы меня кажется недопоняли, или невнимательно прочли:
АВ падает сразу на первой команде, даже если это assert или beep
Такое чуйство что толи указатели загруженного PE файла не пересчитаны, то ли даже и не знаю что думать
← →
Fiend © (2004-03-31 16:55) [9]Следующим шагом, чтобы проверить слова Digitman`a отключил из экспортирующего ехе всё, и оставил только одну экспортируемую функцию в которой стоит assert
и всё равно АВ не пропал. следовательно, т.к. ничто из VCL не подключено и нет никаких там инициализаций, то дело не в ней.
Но вот в чём непонятно
← →
Digitman © (2004-03-31 16:56) [10]
> даже если это assert или beep
assert() использует многие данные из модуля system.pas, раздел initialization которого никто не вызывал
beep() использует библ-ку user32.dll, точка входа в ф-цию MessageBeep которой, возможно, формируется динамически в ходе иниц-ции заинтересованных модулей ехе в ходе его нормальной работы
ShowMessage("asdasdf") использует модуль Forms, который тоже никто не инициализировал, равно как никто не создавал объект Application, интенсивно используемый этим модулем при манипуляциях с формами
кр.того, ехе м.б. собран с пакетами времени выполнения. которые тоже никто не грузил и не инициализировал
← →
Digitman © (2004-03-31 16:59) [11]
> отключил из экспортирующего ехе всё
прелюбопытно, что конкретно ... и каким конкретно образом ...
что, код/данные, принадлежащие System.pas, тоже умудрился отключить ?
← →
Fiend © (2004-03-31 17:07) [12]То Digitman © (31.03.04 16:59) [11]
ну да его ессесно не отключишь. про это я забыл.
Я уже "слегка" запутался: какой вариант ты предлагаешь?
1) переделать всё же в ДЛЛ и ее грузить.
2) использвать командную строку.
3) или может что то еще...
← →
Digitman © (2004-03-31 17:14) [13]если два или более приложений желают использовать один и тот же код , есть прямой смысл вынести алгоритм "утилиты обновления" в DLL, и пусть все заинтересованные приложения обращаются к этой ДЛЛ для запуска этого алгоритма ... самый разумный подход ... для того и существует концепция и механизм динамически линкуемых библ-к
← →
Fiend © (2004-03-31 17:18) [14]То Digitman © (31.03.04 17:14) [13]
Это всё понятно, но хотелось как всегда с минимальной затратой времени, а вылилось в полдня. Ну да ладно, за-то опыт в обасти экспорта из ехе.
ВСЕМ СПАСИБО!!!
обсуждение закрыто!
Страницы: 1 вся ветка
Форум: "Система";
Текущий архив: 2004.05.16;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.083 c