Delphi - разбирать имена в BPL
Возможно ли разобрать такие имена в Delphi? Если так, где я могу получить больше информации?
Пример сообщения об ошибке, когда он не может найти определенную запись в dbrtl100.bpl. Я хочу знать, какую именно функцию он не может найти (единицу, класс, имя, параметры и т. Д.).
---------------------------
myApp.exe - Entry Point Not Found
---------------------------
The procedure entry point @Dbcommon@GetTableNameFromSQLEx$qqrx17System@WideString25Dbcommon@IDENTIFIEROption could not be located in the dynamic link library dbrtl100.bpl.
---------------------------
OK
---------------------------
Я знаю, что это метод GetTableNameFromSQLEx в модуле Dbcommon (у меня Delphi с источниками RTL/VCL), но иногда я сталкиваюсь с приложениями, для которых доступен не весь код (да, клиенты всегда должны покупать весь исходный код для сторонних разработчиков). вещи, но иногда они этого не делают).
Но, скажем, это пример, для которого у меня нет кода или только файлы интерфейса (кто-нибудь BDE.INT?). Какие параметры у него есть (т.е. какая потенциальная перегрузка)? Какой тип возврата у него есть?
Это искажение одинаково для любой версии Delphi?
--jeroen
Изменить 1:
Благодаря Робу Кеннеди: tdump -e dbrtl100.bpl делает свое дело. Нет нужды в -um:
C:\WINDOWS\system32>tdump -e dbrtl100.bpl | grep GetTableNameFromSQLEx
File STDIN:
00026050 1385 04AC __fastcall Dbcommon::GetTableNameFromSQLEx(const System::WideString, Dbcommon::IDENTIFIEROption)
Изменить 2:
Спасибо TOndrej, который нашел эту немецкую статью EDN ( английский перевод Google). Эта статья описывает формат довольно точно, и должна быть возможность создать некоторый код Delphi, чтобы разобраться с этим.
Жаль, что веб-сайт, который упоминает автор (и электронная почта), теперь мертв, но приятно знать эту информацию.
--jeroen
4 ответа
В Delphi не предусмотрена функция, которая будет разбирать имена функций, и я не знаю, где бы она была документирована. Delphi в двух словах упоминает, что утилита "tdump" имеет ключ -um, чтобы отключить обнаруженные символы. Я никогда не пробовал это.
tdump -um -e dbrtl100.bpl
Если это не сработает, то это не выглядит как очень сложная схема, чтобы разобраться в себе. Очевидно, что имя начинается с "@", за которым следуют имя устройства и имя функции, разделенные другим знаком "@". За этим именем функции следует "$qqrx", а затем типы параметров.
Типы параметров кодируются с использованием счетчика символов имени типа, за которым следует тот же формат "@", как и раньше.
"$" Необходимо для обозначения конца имени функции и начала типов параметров. Оставшаяся загадка - часть "qqrx". Это раскрывается в статье, найденной Тондреем. "Qqr" указывает соглашение о вызовах, которое в данном случае является регистром, иначе fastcall. "X" относится к параметру и означает, что он постоянен.
Тип возвращаемого значения не нужно кодировать в искаженном имени функции, поскольку перегрузка в любом случае не учитывает возвращаемые типы.
Если у вас есть C++Builder, посмотрите $(BDS)\source\cpprtl\Source\misc\unmangle.c - он содержит исходный код механизма устранения ошибок, используемого TDUMP, отладчиком и компоновщиком. (C++Builder и Delphi используют одну и ту же схему искажения.)
Также см. Эту статью (на немецком языке). Я полагаю, что искажение возможно обратно совместимо, и в более поздних версиях Delphi представлены новые схемы искажения для новых языковых функций.
Из исходных файлов Delphi 2007:
function GetTableNameFromSQLEx(const SQL: WideString; IdOption: IDENTIFIEROption): WideString;
Кажется, это та же версия, так как у меня также есть тот же.BPL в моей папке Windows\System32.
Исходный код можно найти в [Папках с программными файлами] \ CodeGear \ RAD Studio \ 5.0 \ source \ Win32 \ db
Borland / Codegear / Embarcadero уже давно использует эту кодировку и никогда не давал много подробностей о формате.BPL. Я никогда не интересовался ими, так как ненавижу использовать библиотеки времени выполнения в своих проектах. Я предпочитаю компилировать их в свои проекты, хотя это приведет к гораздо большим исполняемым файлам.