Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Импрот функций из exe. [D6]


Страницы:   1 2 3 4 5 6

Тимохов ©   (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, то оптимизация летела бы к чертям... тоже ИМХО.


Страницы:   1 2 3 4 5 6

Наверх

Титульная страница Поиск, карта сайта Написать письмо