Загружать DLL научились. Работает (естесственно, windows.pas переписан). Но, не умеем выполнять инициализацию юнитов, так как не знаем, откуда взять GetProcAddress и хэндл kernel32. А откуда это вообще берется? Сейчас мы передаём эту информацию в DLL, но это уже после инициализации, что неприятно.
Немного поизучав сишные исходники, я предположил, что надо раскручивать от хэндла модуля, который ссылается на структуру в памяти. Но там не видно ни хэндла кернела ни адреса GetProcAddress. Думаю в ассемблере это более очевидно. Помогите, плиз. Киньте ссылку или намёк где искать.
Кроме windows.pas ссылки на kernel32 и т.п. могут сидеть и в других юнитах, в частности в system Знания берутся из мсдн, а GetProcAddress в WinCE из coredll.dll - в соотв-ии с этими знаниями А вот это вообще не понятно - о какой инициализации речь и что куда передается...
в юнитах в Dephi есть секции initialization, которые выполняются сразу после загрузки DLL. Мы в этот момент ещё не знаем адрес GetProcAddress и хэндл coredll.dll. Отсюда наша проблема. Позже мы передаём эти адрес и хэндл снаружи через специальную экспортируемую функцию и дальше всё работает.
Из этой ссылки совершенно непонятно, откуда взять адрес GetProcAddress. Там только спецификация. Также, ничего неясно про хэндл coredll.dll (или адрес LoadLibrary или GetModuleHandle).
SEA Не понятно главное - dll уже скомпилирована, исходников нет и что-то изменить можно лишь в маш.коде, или же есть исходники ("естесственно, windows.pas переписан") и dll можно перекомпилировать ?
Насчет адресов LoadLibrary и т.п.: разумеется вытащить себя за волосы не получится, поэтому либо статическая линковка (указание coredll в таблице импорта), тогда загрузчик сам все сделает, либо "хак" - наверняка в WinCE как и в прочих вынях адреса системных dll фиксированы, т.е. одинаковы во всех приложениях
Исходники есть, можно перекомпиллировать, но, конечно, Delphi для WinCE не существует. Мне стыдно, но я думал, что статической линковкой управляет не загрузчик, а какой-то стартап код, который не будет работать в WinCE. Попробую со статической линковкой coredll (а таблицы импорта там такие же?).
Но ведь каким-то образом "Загружать DLL научились. Работает..". Значит по крайней мере WinCE поддерживает PE-формат, и значит "таблицы импорта там такие же", и значит просто нужно "перелопатить" исходники (не забыть про system) и привести все импортируемые функции в соответствии с API WinCE
Однако, не работает (с этого всё начиналось, просто я недавно подключился к проекту). Есть предположение, что в WinCE этим занимается всё же не загрузчик, а есть некий метод "вытаскивания себя за волосы".
Да, не-е. WinCE работает с обычным PE-форматом: вот качанул ради интереса пару программок - все как в обычных виндовых экзешниках, только в таблице импорта coredll забита, плюс некоторые параметры PE-заголовка отличаются, в частности Subsystem = 9 (WINDOWS_CE_GUI) вместо 2 (WINDOWS_GUI), ну и тип процессора Machine ес-но может быть специфическим под конкретную железку (а дельфя между прочим ничего кроме x86 родить не может). Поэтому не работать может и из-за несоответсвия параметров PE, и возможно system и windows.pas недочищены и в них могли застрять ссылки на неподдерживаемые функции (в частности, вроде как в СЕ большинство ансишных А-вариантов функций почикано и оставлены преимущественно юникодовские W-версии, а дельфях до 2009 как раз наоборот юзаются А). PS: Не знаю, стоит ли биться с дельфи, если под CE можно free pascal заюзать ? Или ради спортивного интереса ?
Не работает статическая линковка. Пробовал менять subsystem в заголовке PE - не помогает. Обнаружил, что в таблице импорта в EXE, скомпиллированном под WinCE, отсутствуют LoadLibraryW, GetModuleHandleW, GetProcAddressW (хотя они вызываются). Так что процесс вытягивания себя за шнурки (или за волосы) всё же сущестует. Кстати, адреса GetProcAddressW на разных компьютерах разные.
Поправочка. LoadLibraryW, GetModuleHandleW, GetProcAddressW присутствуют в секции import в виде номеров. Однако, статически подлинковать их по номерам из Delphi всё же не получилось. Будем хакать - вписывать адреса GetModuleHandleW, GetProcAddressW в DLL, лучшего варианта не нашли.