|
Delphi. Хранение методов в памяти | ☑ | ||
---|---|---|---|---|
0
H A D G E H O G s
20.05.15
✎
14:54
|
Дня доброго.
Тема создана для темы: Иногда они возвращаются.... Хранение методов в памяти. Там есть процедурка function MethodToProcedure(self: TObject; methodAddr: pointer) : pointer; Я так и не понял, как она работает, и вот пришло расскаивание - мне нужна ее 64-х битная сестра-близнец. Помогите. |
|||
1
H A D G E H O G s
20.05.15
✎
15:00
|
Вернее, я сейчас понимаю, как там все работает - выделяется кусок памяти, в нее записывается код на ассемблере, и возвращается адрес этого куска памяти как указатель. Код запускает выполнение по этому адресу (создает поток, например), выполняется ассемблеровский код, который передает управление по адресу methodAddr.
Мне нужен такой же асм. код под 64-х битное приложение. |
|||
2
Кирпич
20.05.15
✎
15:27
|
(1) на 64-х может сразу не прокатить. там может быть защита на выполнение кода в данных. нужно как то особо память выделять чтобы давало доступ на выполнение.
|
|||
3
Кирпич
20.05.15
✎
15:30
|
+(2) в 64-x еще есть заморочка про вызовы функций. в 32 там всякие stdcall, cdecl и т.п. В 64-x только один способ.
|
|||
4
Garykom
гуру
20.05.15
✎
15:32
|
(0) код в lazarus (fp x64) не работает?
|
|||
5
Кирпич
20.05.15
✎
15:32
|
вот две грабли, на которые ты можешь наступить в своём светлом пути.
об остальных граблях сообщу через неделю. шутко :) |
|||
6
H A D G E H O G s
20.05.15
✎
15:33
|
(3) Какой?
|
|||
7
H A D G E H O G s
20.05.15
✎
15:35
|
(2) гхммм.
В разделе защиты памяти ничего про это не говорится. https://msdn.microsoft.com/en-us/library/windows/desktop/aa366786(v=vs.85).aspx |
|||
8
H A D G E H O G s
20.05.15
✎
15:37
|
(4) Нет, в Дельфях.
|
|||
9
Кирпич
20.05.15
✎
15:38
|
(6) забыл как называется. поню что параметры сначала в регистрах, остальное в стек. на MSDN по русски расписано все подробно. щас голова болит искать неохота.
|
|||
10
MMF
20.05.15
✎
15:38
|
Робко интересуюсь конечной целью сего действа
|
|||
11
H A D G E H O G s
20.05.15
✎
15:39
|
(9) fastcall
|
|||
12
Кирпич
20.05.15
✎
15:40
|
(7) ну я щас точно не помню. прсто когда я делал когда то jit компилятор у меня такая фигня была. на 32 работало, на 64 глюк. надо искать свою писанину. поню только что какие то атрибуты выделенной памяти присваивал.
|
|||
13
H A D G E H O G s
20.05.15
✎
15:40
|
(10) Хочу из созданного потока вызывать методы объекта, создавшего поток.
|
|||
14
Кирпич
20.05.15
✎
15:40
|
(11) не. это не то.
|
|||
15
H A D G E H O G s
20.05.15
✎
15:42
|
(10) Thread-callback функция размещена в секции published объекта.
|
|||
16
Кирпич
20.05.15
✎
15:43
|
||||
17
Кирпич
20.05.15
✎
15:45
|
(10) он себя когда нибудь погубит этими килабайтами и стеками
|
|||
18
MMF
20.05.15
✎
15:46
|
(13) вангую много-много геморов с синхронизацией потоков, даже если сам вызов удастся... странная идея
|
|||
19
H A D G E H O G s
20.05.15
✎
15:54
|
(18) Это все понятно, дыры заткнем ожиданиями на мьютексах, но пока их нет. В 32-х разрядах все работает как часы.
|
|||
20
Кирпич
20.05.15
✎
16:02
|
в гугле, как всегда, всё готовое уже есть
http://stackoverflow.com/questions/8283490/how-to-turn-a-method-to-a-callback-procedure-in-64bit-delphi-xe2 |
|||
21
Кирпич
20.05.15
✎
16:04
|
там и про память чо я говорил
Q := VirtualAlloc(nil, lCount, MEM_COMMIT, PAGE_EXECUTE_READWRITE); |
|||
22
Кирпич
20.05.15
✎
16:07
|
https://yandex.ru/yandsearch?&clid=2186620&text=MethodToProcedure%20x64
самая первая ссылка. H A D G E H O G s, ты тролль |
|||
23
H A D G E H O G s
20.05.15
✎
16:08
|
(22) Бугага. nice
Искал воот так: https://yandex.ru/search/?text=MethodToProcedure%2064x&clid=2186620&lr=213 |
|||
24
H A D G E H O G s
20.05.15
✎
16:08
|
Всего одна ошибка в строке поиска и такие проблемы.
|
|||
25
H A D G E H O G s
20.05.15
✎
16:09
|
Спасибо огромное.
|
|||
26
MMF
20.05.15
✎
16:21
|
можно придумать десяток надежных способов передачи события и данных между потоками стандартными средствами, без всякого хака
|
|||
27
H A D G E H O G s
20.05.15
✎
16:28
|
(26) Проблема не в данных, проблема в области видимости.
|
|||
28
Кирпич
20.05.15
✎
16:28
|
(26) да тут потоки не главное. это про то, как приляпать к объекту callback, который будет вызывать например windows, в котором используются данные конкретного объекта (здесь этот объект - поток)
|
|||
29
Кирпич
20.05.15
✎
16:31
|
+(28) этот хак используется в Delphi везде. Даже обычная кнопка на форме так работает. Ибо windows так устроена.
|
|||
30
Garykom
гуру
20.05.15
✎
16:33
|
(робко) а может лучше на fp? ...
а то под linux то как? |
|||
31
DmitrO
20.05.15
✎
16:34
|
(28)все равно не понятно зачем для этого размещать код в области данных :)
есть же наверно в delphi процедурный тип |
|||
32
Кирпич
20.05.15
✎
16:35
|
(31) ну предложи другой вариант
|
|||
33
Garykom
гуру
20.05.15
✎
16:35
|
(31) интерпретируемый интерпретатор
|
|||
34
vde69
20.05.15
✎
16:38
|
я для своей поделки использовал
HANDLE CreateFileMapping( HANDLE hFile, //дескриптор физического файла LPSECURITY_ATTRIBUTES lpFileMappingAttributes, //игнорируется. Должно быть NULL DWORD flProtect, //флажки защиты доступа DWORD dwMaximumSizeHigh, //старшие байты размера DWORD dwMaximumSizeLow, //младшие байты размера LPCTSTR lpName //имя проекции ); |
|||
35
Кирпич
20.05.15
✎
16:39
|
Чота слабо припоминаю, что в новых версиях Delphi что то поменялось по этой теме. щас загуглю.
|
|||
36
vde69
20.05.15
✎
16:39
|
(34) при указании соответствующих флагов этот файл видится из любых потоков/процессов
|
|||
37
H A D G E H O G s
20.05.15
✎
16:42
|
(34) (36) Што это? Зачем это?
|
|||
38
Кирпич
20.05.15
✎
16:42
|
(36) веткой ошибся
|
|||
39
vde69
20.05.15
✎
16:46
|
(37) через этот файл (или поток, там то же есть) можно передавать данные между потоками.
Как я понимаю тебе ведь нужно тупо данные передавать, иначе ты-бы юзал динамическое связывание DLL |
|||
40
H A D G E H O G s
20.05.15
✎
16:49
|
(39) Ты действительно ошибся веткой :-)
|
|||
41
Кирпич
20.05.15
✎
16:50
|
vde69 кажися написал какого то бота для генерации постов на тему программирования и он щас над нами глумится
|
|||
42
H A D G E H O G s
20.05.15
✎
16:50
|
(39) Проблема описана в сообщении (11) в ветке
Delphi. Методы объектов как то по другому хранятся в памяти? Ее и решаем. |
|||
43
Кирпич
20.05.15
✎
17:02
|
А. Вспомнил. В Delphi же сейчас есть записи с методами. Методы записей наверное обычные процедуры. Можно вместо класса использовать такие записи.
|
|||
44
H A D G E H O G s
20.05.15
✎
17:03
|
(43) Бррр, моя душа ерепениться от таких нововведений.
|
|||
45
Кирпич
20.05.15
✎
17:03
|
(42) попробуй (43). у меня теперя delphi нету. перешел на lazarus
|
|||
46
Кирпич
20.05.15
✎
17:04
|
(44) нуачо. как раз для твоего случая
|
|||
47
Кирпич
20.05.15
✎
17:04
|
и без хаков.
|
|||
48
H A D G E H O G s
20.05.15
✎
17:05
|
(45) Нет, у меня готовая dll-ка 32-х разрядная, отлаженная. Осталось ее сестричку под 64-x сделать и все.
|
|||
49
vde69
20.05.15
✎
17:07
|
судя по (13) >>>>Хочу из созданного потока вызывать методы объекта, создавшего поток.
я понимаю дело так есть основной загрузчик, этот загрузчик резервирует память и помещает в нее некий код, после запускает отдельный процесс который должен использовать код созданый загрузчиком? почему запускаемый загрузчиком новый процесс не может загрузить DLL позднего связывания и спокойно юзать все, что надо? а вот передача параметров/данных между загрузчиком и новым процессом и должна идти через публикуемый в памяти файл. еще по сабжу: в подобных поделках нужно использовать SDK операционки а не дельфей и тог-да не будет проблем ни с правами ни с чем еще... |
|||
50
H A D G E H O G s
20.05.15
✎
17:09
|
(49) Помнишь, я приходил к тебе на собеседование. Скажи сферу деятельности предприятия, в котором проходило наше собеседование?
|
|||
51
Garykom
гуру
20.05.15
✎
17:12
|
(50) ...где попкорн?
|
|||
52
Кирпич
20.05.15
✎
17:13
|
(49) какой ты сложный, чувак
|
|||
53
DmitrO
20.05.15
✎
17:18
|
(32)вот такое разве нельзя сделать на delphi?
//класс с функцией членом foo class c { public: int foo(int i) { return 6 + i; }; }; typedef int (c::*fType)(int); //объявление типа fType как указателя на функцию класса с параметром типа int и возвращающей int fType pf = &c::foo; //присваивание адреса функции foo класса с в переменную pf c* pc = new c(); //создание объекта типа с в переменную pc int r = (pc->*pf)(2); //вызов функции из переменной pf с параметром 2, результат: r = 8; delete pc; //уничтожение объекта |
|||
54
Кирпич
20.05.15
✎
17:28
|
Не. Нужно метод объекта вызвать как обычную функцию, но в этом методе объекта иметь доступ к полям объекта.
Надо примерно так. (сомневаюсь что правильно написал) class c { public: int X; int foo(int i) { return 6 + X; }; }; typedef int (*fType)(int); fType pf = (fType)&c::foo; c* pc = new c(); int r = pf(2); delete pc; |
|||
55
sapphire
20.05.15
✎
17:31
|
TMethodToProc = packed record
popEax: Byte; pushSelf: record opcode: Byte; Self: Pointer; end; pushEax: Byte; jump: record opcode: Byte; modRm: Byte; pTarget: ^Pointer; target: Pointer; end; end; function MethodToProcedure(self: TObject; methodAddr: Pointer): Pointer; var mtp: ^TMethodToProc absolute Result; begin New(mtp); with mtp^ do begin popEax := $58; pushSelf.opcode := $68; pushSelf.Self := Self; pushEax := $50; jump.opcode := $FF; jump.modRm := $25; jump.pTarget := @jump.target; jump.target := methodAddr; end; end; |
|||
56
Кирпич
20.05.15
✎
17:32
|
(55) да уже давно решили. тут просто болтовня уже.
|
|||
57
Garykom
гуру
20.05.15
✎
17:35
|
А зачем вообще такое нужно кроме случаев юзания чужого скомпиленного кода?
|
|||
58
DmitrO
20.05.15
✎
17:35
|
(54) все правильно, за малым исключением того что X не инициализирован.
"иметь доступ к полям объекта" - ну кабы это не проблема если эта функция-член не stаtic. можно добавить к классу конcтруктор: c() {X = 10;} и тогда после: int r = pf(2); r будет равна 16 |
|||
59
DmitrO
20.05.15
✎
17:37
|
ну вызов только так надо делать
int r = (pc->*pf)(2) с использованием экземпляра класса, а как иначе-то? |
|||
60
Кирпич
20.05.15
✎
17:38
|
(58) а так?
class c { public: int X; int foo(int i) { return 6 + X + i; }; }; |
|||
61
DmitrO
20.05.15
✎
17:39
|
(60)без проблем
|
|||
62
DmitrO
20.05.15
✎
17:40
|
вот если бы функция-член была объявлена как ststic тогда она ничем бы не отличалась от просто глобальной функции, и вызвать ее можно было бы без экземпляра класса.
|
|||
63
DmitrO
20.05.15
✎
17:41
|
но тогда в ней (разумеется) не получить доступ к данным экземпляра класса.
|
|||
64
DmitrO
20.05.15
✎
17:42
|
на обджект паскале все тоже должно быть, я думаю..
|
|||
65
DmitrO
20.05.15
✎
17:44
|
кстати функцию-член можно запросто сделать и виртуальной (метод)
|
|||
66
Кирпич
20.05.15
✎
17:44
|
(64) да там всё точно так же.
а так что будет class c { public: int X; int foo(int i) { return 6 + X + i; }; }; |
|||
67
Кирпич
20.05.15
✎
17:45
|
ой
class c { public: int X; int foo(int i) { return 6 + this->X + i; }; }; |
|||
68
DmitrO
20.05.15
✎
17:46
|
6 + this->X + i;
6 + X + i; это одно и тоже, эквивалент, после компилятора даже код будет бинарно одинаковый |
|||
69
DmitrO
20.05.15
✎
17:46
|
они щас умные, что звиздец..
|
|||
70
H A D G E H O G s
20.05.15
✎
17:48
|
Вашу бы енергию, да в мирное русло...
|
|||
71
DmitrO
20.05.15
✎
17:51
|
например в объектах можно так написать:
void Kill_Himself() { delete this; }; применяют для когда объект сам управляет своим временем жизни |
|||
72
DmitrO
20.05.15
✎
17:51
|
в каждом COM объекте кстати такой код есть :)
|
|||
73
Кирпич
20.05.15
✎
18:29
|
(58) не знаю как у тебя получилось 16. у меня такое даже не компилится и правильно делает.
приведение типов: невозможно преобразовать "int (__thiscall wmain::c::* )(int)" в "fType" |
|||
74
Американец
20.05.15
✎
19:11
|
(63) >>тогда в ней (разумеется) не получить доступ к данным экземпляра класса.
Многие Win32 callback'и имеют дополнительный нетипизированный параметр. Туда можно передать this и иметь доступ к экземпляру класа. Если callback твой - добавь параметер для this. |
|||
75
vde69
20.05.15
✎
19:20
|
(50) здание точно не помню, это или цивильное здание с шлюзом на 1 человека или говно дом напротив биржи. (фин холдинг был... а направлений там много было ...)
но дело не в этом а в том, что я не понимаю главное: нужно использовать "свое" адресное пространство или "чужое"??? из сабжа я понял, что "чужое", если это не так - то разумеется я чушь порол :) |
|||
76
H A D G E H O G s
20.05.15
✎
19:30
|
(75) Все, теперь я понял, что ты - настоящий :-)
Адресное пространство - свое. |
|||
77
vde69
20.05.15
✎
20:49
|
(76) тогда процедурный тип сделай и должно все штатно без плясок взлететь
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |