![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Импрот функций из exe. [D6]
Тимохов © (2004-06-29 11:44:00)Прочел тут как-то, что импортировать функции можно не только из dll, но и из других exe. Попробовал сделать динамической загрузкой, получилось :)) Я сделал один dpr, даже без begin и end, т.е. одна функция и секция exports.
Вопросы:
1. Что происходит при загрузке exe череp LoadLibrary? Для dll, если не ошибаюсь вызывается стартовая функция библиотеки с соответствующим флагом, что-то типа dllproc process_attach (на память не помню). Что вызывается для exe? У него вроде нет такой функции.
2. Почему у меня не сработал такой код в библиотеке
procedure f();
begin
MessageBox(0, 'text', 'caption', MB_OK);
end;
При вызове f из другого приложения впесто текстов получается ерунда (т.е. случайная область памяти).
И совершенно нормально сработал такой
procedure f();
var
kText: packed array[0..4] of char;
kCaption: packed array[0..7] of char;
begin
kText[0] := 't';
kText[1] := 't';
kText[2] := 't';
kText[3] := 't';
kText[4] := #0;
kCaption[0] := 'c';
kCaption[1] := 'a';
kCaption[2] := 'p';
kCaption[3] := 't';
kCaption[4] := 'i';
kCaption[5] := 'o';
kCaption[6] := 't';
kCaption[7] := #0;
MessageBox(0, @kText, @kCaption, MB_OK);
end;
В последнем случае все вывелось корректно.
Тимохов (2004-07-13 15:35:00) [21]
> 2. Инициализация EXE (VCL)
я тоже не знаю как exe инициализируется. Как dll вроде в msdn описано, а как exe - не знаю.
так что мыслей нет.
-SeM- (2004-07-13 15:31:00) [22]А вообще одним MessageBox сыт не будешь. После него все равно будут вопросы
На чем тормознулся я:
1. Как отловить момент загрузки/выгрузки (DLLEntryPoint)
2. Инициализация EXE (VCL)
Будут мысли, предположения - высказывайте, будем думать.
Тимохов (2004-07-13 15:27:00) [23]фиг его знает, с чем это связано. У меня тоже, то работает, то нет. Даже понять сложно логику зависимости. :(((
Я решил ждать выхода из отпуска Игоря Шевченко. Он говорил, что посмотрит.
-SeM- (2004-07-13 15:25:00) [24]Странно, у меня оба примера работают без ошибок (D7, Me). Как и работало два месяца назад
Даже если переделать так [82]:
procedure test;
begin
MessageBox(0, 'hi', 'hi', MB_OK);
end;
// Пример со строковой константой
procedure ExportFunctionWithStringConst();
begin
Test;
end;
Может связано с директивами компилятора? Даю для сравнения мои:
-$A8
-$B-
-$C+
-$D+
-$E-
-$F-
-$G+
-$H+
-$I+
-$J-
-$K-
-$L+
-$M-
-$N+
-$O+
-$P+
-$Q-
-$R-
-$S-
-$T-
-$U-
-$V+
-$W-
-$X+
-$YD
-$Z1
-cg
-AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;
-H+
-W+
-M
-$M16384,1048576
-K$00400000
Тимохов (2004-07-13 12:57:00) [25]
> SammIk © (12.07.04 20:37) [86]
во-во
SammIk (2004-07-12 20:37:00) [26]Интересно выслушать и другие мнения
SammIk (2004-07-12 20:37:00) [27]Интересно выслушать и другие мнения
SammIk (2004-07-12 19:02:00) [28]Сеичас лежу в NTDLL посмотрим как он грузит.
На сеи момент известно, что LoadLibrary обращается к ф-ии
LdrLoadDLL из NTDLL.DLL
Тимохов (2004-07-12 18:57:00) [29]
> Я бы пока не советовал юзать exe как длл, но никто не запрещает.
я и не собираюсь.
этот вопрос возник как теоретический с возможным будущим применением.
SammIk (2004-07-12 18:26:00) [30]Дело в том, что загружается exe превосходно.
И адрес процедуры берет верно, и релоки добовляет(но странно как-то).
Разобрался с релоками, в таблице релоков есть ссылка на изменение
адресов:
CODE:0044DBF6 push 44DC08h<<<Конкретно
CODE:0044DBFB push 44DC08h<<<Тут тоже
И больше, в интересующеи нас области данных, ничего не релокируется!?!? Ни вызовы, ни что!!
По идее еще надо это релокать:
CODE:0044DBED call pMessageBoxA
Но не релокается.
--------------------------------
Так же, глядя в дебагере, ось не исправляет адреса(!?!?!?) хотя они(релоки, фиксапы[как ни называи]) есть!
--------------------------------
Вообщем эта история требует детального изучения)))
Я бы пока не советовал юзать exe как длл, но никто не запрещает.
НО при условии, что не будет вызова других ф-ии
Тимохов (2004-07-12 17:58:00) [31]
> Лично у меня не работал ни первыи, ни второи вариант.
у меня дома один работает, второй - нет.
А вот на работе также - оба не работают.
Перефразирую вопрос, чтобы не свести данный к топик к личной переписке
Как использоваться exe в качестве dll, загружая с помощью LoadLibrary?
SammIk (2004-07-12 17:55:00) [32]
Из дизасма:CODE:0044DBF4 public ExportFunctionWithStringConst
CODE:0044DBF4 ExportFunctionWithStringConst proc near
CODE:0044DBF4 push 0
CODE:0044DBF6 push 44DC08h <<<Конкретно компилер подвел нас, записал пуш статически((CODE:0044DBFB push 44DC08h <<<Тут тоже
CODE:0044DC00 push 0
CODE:0044DC02 call pMessageBoxA
CODE:0044DC07 retn
CODE:0044DC07 ; ---------------------------------------------------------------------------
CODE:0044DC08 db 68h ; h<<Наша HI
CODE:0044DC09 db 69h ; i
С дугои функциеи дела проще:
CODE:0044DBD0 public ExportFunctionWithCharArray
CODE:0044DBD0 ExportFunctionWithCharArray proc near
CODE:0044DBD0
CODE:0044DBD0 var_2 = byte ptr -2
CODE:0044DBD0 var_1 = byte ptr -1
CODE:0044DBD0
CODE:0044DBD0 push ecx
CODE:0044DBD1 mov byte ptr [esp+0], 68h
CODE:0044DBD5 mov [esp+3+var_2], 69h
CODE:0044DBDA mov [esp+3+var_1], 0
CODE:0044DBDF push 0
CODE:0044DBE1 lea eax, [esp+4] <<Тут переменные грузит из стека, динамически
CODE:0044DBE5 push eax
CODE:0044DBE6 lea eax, [esp+8]
CODE:0044DBEA push eax
CODE:0044DBEB push 0
CODE:0044DBED call pMessageBoxA
CODE:0044DBF2 pop edx
CODE:0044DBF3 retn
CODE:0044DBF3 ExportFunctionWithCharArray endp ; sp = -10h
___________________________________________
А это вообще одельно
CODE:0044DBED call pMessageBoxA
Он сначала кидает нас сюда:CODE:00406D28 pMessageBoxA proc near ;
CODE:00406D28 ;
CODE:00406D28 jmp ds:MessageBoxA_0
CODE:00406D28 pMessageBoxA endp
А потом джампаем сюда:.idata:00450490 extrn MessageBoxA_0:dword ;
Таким образом, когда первую грузит вторая прога, то мы при вызове
CODE:0044DBED call pMessageBoxA
поподаем в адресное пространство вызывающеи проги, а не нашеи
псевдодлл.
А по этому адресу малоли чего может быть.
Лично у меня не работал ни первыи, ни второи вариант.
>>>Тоесть правильно что у тебя ацессвиол, это следствие того, что мы колимся в кудато-туда, а не туда куда надо))
Релоки есть, но мне надо про них скил поднять.
Потом скажу что релокают, а что нет))
Тимохов (2004-07-12 12:05:00) [33]
> Piter © (11.07.04 12:43) [77]
потерпите - я же объяснил в чем дело.
вопрос не помрет - уверяю вас. :)))
SammIk (2004-07-11 20:17:00) [34]Слухаи, и мне пошли свои ваилик, тож интересно скомпилить да поразбирать.
sammik(DOG)mail(DOT)ru
Скорее всего в понедельник скажу, вот экзамен сдам))
Piter (2004-07-11 12:43:00) [35]И когда мы увидим ответ? Ветка умерт к тому времени?
Piter (2004-07-08 12:16:00) [36]Удалено модератором
Примечание: Offtopic
Тимохов (2004-07-06 10:37:00) [37]
> Piter © (05.07.04 23:46) [74]
Игорь сказал, что нам придется подождать, т.к. у него отпуск.
Но после он обязательно посмотрит.
Piter (2004-07-05 23:46:00) [38]Игорь Шевченко (01.07.04 00:50) [70]
ну так как ваше мнение?
GrayFace (2004-07-03 07:49:00) [39]Ой. Я ступил в ответе на [45].
А так точно должно работать:
procedure ...;
const Text:ShortString='text'; Caption:ShortString='Caption';
begin
MessageBox(0, Text, Caption, MB_OK);
end;
GrayFace (2004-07-03 07:41:00) [40]Похоже, все это связано именно с System и SysUtils. В Delphi есть менеджер памяти, находящийся в одном из этих модулей. Глобальное выделение памяти идет чераз него, а, значит, не идет в данном случае.
Попробуй так:
procedure ...;
const Text='text'; Caption='Caption';
begin
MessageBox(0, Text, Caption, MB_OK);
end;
Digitman [45]
>задействуя дин.тип, ты задействуешь как минимум модули system и sysutils, которые не инициализированы
Я так не думаю. ИМХО, это обычный PChar с выделением памяти. Если бы каждый раз, когда нужна строка, компилятор ставил обращение к System и/или SysUtils, то оптимизация летела бы к чертям... тоже ИМХО.