OCTAGRAM
ada Delphi Когда случился несчастливый релиз Delphi 8, несчастливый тем, что там был только .NET, меня бесили немутируемые строки. Раньше же как-то работало с мутируемостью, а вот теперь не работает, и всё тут, счётчика ссылок не хватает. Дополнить трассирующую сборку мусора счётчиком ссылок кому-то религия не позволила, и из-за этого теперь страдать.

Много лет спустя пишу на Аде и обращаю внимание на то, что пишу практически в стиле единственного присваивания, благо адский declare-begin-end позволяет, и благо, начиная с Ada 2012 всё больше вещей можно записать выражениями. В этом плане Делфи уступает даже 83ей Аде. По принципу наименьших прав большинство значений между declare и begin — константы, и строки — соответственно, тоже. Кроме того, хотя есть Делфи-подобные строки (Unbounded_String в стандартной библиотеке и Universal_String в Матрёшке Вадима Годунко) со счётчиком ссылок, быстрее всего работают строки, размещаемые на стеке. Это которые самый обычный type String is array (Positive range <>) of Character, по принципу действия похожий на вариадические массивы в C99 и alloca(). После размещения на стеке у них размер поменять нельзя, а, значит, и нет особого смысла им не быть константой. И так получилось разделение на де факто немутируемые обычные строки и мутируемые строки в динамической памяти, похоже на String и StringBuilder .NET.

В каком-то смысле вернулся к тому, с чего начинал, с поправкой на то, что Unbounded_String как значение вполне себе пригоден для хранения в записях, массивах и контейнерах, в отличие от.
OCTAGRAM
ada Delphi Почему-то компилятор жутко тупит над производными типами. Вот, например, type TDateTime = type Double. Логично сделать так:

TDateTime(SysUtils.StrToFloat(…))
Ан нет, E2089 Invalid typecast. Может, проблема в том, что результат StrToFloat — Extended, а не Double?
TDateTime(Double(SysUtils.StrToFloat(…)))
Всё равно E2089 Invalid typecast. Да как же так? Сам ты инвалид!

Что самое удивительное, работает, если приведение типа НЕ ДЕЛАТЬ:
SysUtils.FormatDateTime(…, SysUtils.StrToFloat(…))
Вот так компилируется и само приводится сквозь все Extended, Double и TDateTime, хотя я бы сильно не хотел, чтоб число с плавающей точкой случайно могло стать OLE датой/временем.

Ещё это сильно мешает привязки делать. По привычке возьмёшь напишешь type TPluginItem = type Pointer, и начинает тебе компилятор мозг выедать на ровном месте, а на неровном — соответственно, не выедать. Плюнешь, переделаешь в указатель на пустую запись с уникальным именем. Вот теперь получился указатель, который «не похож» на произвольно взятый другой указатель, но, к сожалению, всё ещё похож на указатель, чего лишний раз не хотелось бы, и от чего производный тип должен был спасти. Гипотетически для непохожести можно завернуть ещё дополнительно в запись, но тогда может сломаться работа с внешней библиотекой, ибо Delphi получает запись-результат всегда через дополнительный указатель, даже если она меньше размера двух указателей, как предписано stdcall. И тем более результат с плавающей точкой таким образом не приедет через регистр сопроцессора.

А вот на Аде берёшь и пишешь type OLE_Date_Time is new Long_Float или type Plugin_Item_Type is new Address, и работает это именно так, как ожидаешь. Одно в другое случайно не сконвертируется, а по требованию — всегда пожалуйста, без этих дурацких непонятных ошибок. И, конечно, на Аде, когда пишешь пакет, можно просто написать в публичной части type Plugin_Item_Type is private, и всё, внутреннее устройство для внешнего мира становится непрозрачно. Если нужно, функции конвертации из/в Address можно написать в дочернем пакете, чтоб глаза не мозолило в родительском. А то в Delphi, C и C++ вечно свалка в пространстве имён, хочется закрыться руками от падающих отовсюду в пространство имён гор мусора.
OCTAGRAM
indy OpenSSL Delphi Решил не так давно делать веб-запросы в программе на необновлённом Indy. Кто его знает, этого заказчика, сможет он свежую поставить или нет. Узнал много нового. Оказывается, обычная библиотека OpenSSL к Indy не подходит, потому что там требуются некоторые функции специально для Indy вроде SSL_CTX_set_options_indy. Думаю, раз она в комплект не входит, надо скачать её с сайта Indy. А вот и нет! Где библиотека, где патч, интересные люди, однако.

Полазив по форумам, нашёл такую ссылку. Скачал самую свежую. Не подошло. Методично качал другие версии с конца, потом методом дихотомии, потом тупо взял самую старую версию. Смотрел в ФАРе, есть там эти долбаные нестандартные функции или нет. Нету. Нигде. Заглянул в архив и там прямо явно видно версии с Indy в названии. Наверное, оно. Скачал 0.9.8l. Не подошло. Скачал 0.9.8h. Не подошло. Действительно, если смотреть, что там внутри, то префиксы _indy видать, но это не всё, что нужно. Оказывается, IdSSLOpenSSLHeaders10.pas там не для красоты, и без него не работает. Я ведь хотел, чтоб Indy не пересобирать, думал, на интерфейс к новым функциям можно забить, а оказывается, что там и основной интерфейс переделан, поэтому каких-то нестандартных функций нет. Впрочем, пересобирать весь Indy не пришлось, достаточно было положить только этот файлик под правильным именем в директорию проекта, он заменил собой предустановленный dcu и нормально скомпоновался с остальными модулями.

Потом выяснилось, что хотя в Delphi 2007 версия Indy 10, но если бы я на сайте Indy зашёл в Indy 9, то там была бы ссылка на SSL Support DLL's, а оттуда — на Fulgan. Если б знал, что там всё настолько плохо, попробовал начать с WinInet. Авось его неумение в SNI проканает.
OCTAGRAM
Linux Delphi Раньше я видел в действии только Делфи для Мак ОС Десять. Скомпилировал при помощи dccosx.exe консольный «Привет, мир!», всё прошло успешно, но на Мак ОС Десять, правда, не запустилось, потому что у меня был Тигр, а надо было хотя бы Леопард. Кому надо, зачем надо, так хорошо без него всё было, но как обычно, просто надо, и всё тут. На XP Safari 5 можно было установить, а на более новый Тигр — всего лишь Safari 2. И FireFox 26 на XP против FireFox 3.6 на Тигре. Про Делфи XE2 можно было сказать: «И ты, Брут?» Но примечательно, что компилировалось это всё дело без доступа к Мак ОС Десять, ни к Тигру, ни к Леопарду, ни к какой.

А вот на Линуксе я же помню, что вылезает, если с ЦентОСа на Дебиан перенести бинарник. Сразу то символ в glibc не той версии, то сегфолт, то ещё что-нибудь не заладится. Интересно, как с этим новый Делфи справляется. Ведь ему же не дают полапать конфигурацию операционной системы разработчика, и он не может к ней глубоко привязаться, как это любит делать всё автотулзовое и вообще чуть ли не всё линуксовое.

Собственно, пока я окончательный бинарник так и не смог получить, а только .o. То есть, так же просто, как с Мак ОСом, уже не работает. Если пытаться что-то сделать из IDE, хотя бы Build или Compile, без Run, при любом раскладе IDE требует подключить к paserver на Linux, а если нет, то и компилировать не будет. Попытался задействовать в качестве платформы paserver «Bash на Ubuntu», то есть, WSL, и не смог скопировать paserver туда. Помедитировал на вывод mount и ls / в этом bash, не нашёл ничего похожего на файловую систему Windows. Это действительно параллельная Вселенная. Можно, конечно, на сайт залить, а потом wget'ом скачать, но решил дождаться установки Creators Update, а пока пойти другим путём.
OCTAGRAM
Linux ada Delphi Почитал сорцы в linuxrtl, бросилось в глаза MarshaledAString вместо PAnsiChar. Открыл System.pas, нашёл там при включенном NEXTGEN такое:
_PAnsiChr = _PAnsiChar;
MarshaledAString = _PAnsiChr;
При этом _PAnsiChar не объявляется, то есть, он встроенный. Без NEXTGEN _PAnsiChr = привычному PAnsiChar. Напрашивается мнение, что из MarshaledAString пытаются лепить типа-не-указатель, который надо класть в System.TMarshal. Судя по тому, что WriteLn(X) и X[0] := '2' компилируются, природа этого типа пока ещё не совсем замаскирована.

Также огорчило, что до сих пор нет нормальных 32битных символов и строк. В языке Ада они уже 12 лет как появились как неотъемлемая часть стандарта. Как можно идти на Линукс без 32битных строк? В API открытых библиотек Юникод, сколько я видел, любой libidn возьми, всегда представлен 32битными строками. Открыл System.pas, увидел там type UCS4Char = type Cardinal для всех платформ, где Cardinal — это беззнаковое 32-битное целое, а type … = type … в Делфи делает новый тип, не совместимый со старым без приведения типа, аналог адского type … is new …

Ещё посмотрев по сторонам, нашёл StdDefTypes.inc , а в нём — type wchar_t = Int32

Ни методов TMarshal, ни попыток аналогично скрыть указатель вроде Marshaled32String, ничего такого. Высокопоставленные китайские чиновники с именами из иероглифов за пределами BMP, а также все причастные, которым текст с этими именами надо обрабатывать, не одобряют это.
OCTAGRAM
arc Linux совместимость Delphi Посмотрел немного на Delphi для Linux. Компилятор командной строки называется dcclinux64.exe. И там ARC для ссылок на объекты, что было бы очень круто, если не отсутствие поддержки ARC в компиляторах для Windows и Mac OS X. Ну покажите мне такого человека, которой будет писать из-под Винды (и не из-под чего другого) на Линукс (и не подо что другое). Потому что если в целевых платформах затёсывается хоть одна не-ARC, это во всём общем коде становится нельзя положиться на его наличие, всюду вылезают лестницы try-finally, то есть, ARC, считай, что и нет, наоборот, только геморроя добавляется предусматривать постоянно оба случая.

Это напоминает поведение хозяина, который, чтобы собаке было не так больно, режет ей хвост по частям. Linux уже там, а Windows и Mac OS X — ещё здесь. Ожидается, что и Windows будет там, но ещё нет, и пока крутитесь, как хотите.

Для Delphi обычно параллельно выпускается комплементарный C++ Builder, зеркалирующий в C++ особенности Delphi вроде свойств объектов, неявных метаклассов или пресловутого ARC, и синхронизирующий ABI вплоть до наследования классов между языками. Но для Linux я никакого такого компилятора не увидел. Нет bcclinux64.exe, и из IDE, если создать новый консольный проект, нельзя выбрать целевую платформу Linux. Немного неожиданно, ведь кроме одного все компиляторы C++ Builder основаны на clang и LLVM, в том числе для Android, который почти Linux.

Забавно, что для Win32, наоборот, есть сразу два компилятора, bcc32.exe без ARC и bcc32c.exe с ARC. Там тоже режут хвост по кусочкам, но начинают с другого конца. Ох, копец.

Если вдруг ограничиться только Линуксом, только Делфи (без комплементарного Делфям C++, но всё остальное, конечно, можно, включая Аду GNAT и комплементарный Аде G++), и только из-под Виндоуз, тогда всё супер. Хоть в чём-то Делфи становится лучше Ады. А так — копец.
OCTAGRAM
ada Delphi В Делфи нет встроенной безопасной функции, обратной Ord, для произвольных перечисляемых типов. Чтоб, если я поделал арифметику и намылился привести тип обратно, программа не тихо проглотила ошибку, а сразу настучала, куда следует.

TestValue := TCalDayOfWeek(20);
Такой оператор молча проглотил ошибку, что меня как адиста, конечно, возмущает.
TestValue := dowMonday + 20;
Такой оператор не компилируется, но направление мысли было верным. Ещё немного подумав, я нашёл ближайший аналог на Делфи:
TestValue := dowMonday;
Inc(TestValue, 20);
В этом случае бросается ERangeCheckError, что и требовалось.

На Аде я бы написал TCalDayOfWeek'Val (выражение) без необходимости во временной переменной.

Но в языке Ада, наоборот, нет такого всеядного Inc, как в Делфи. Как адаисту, мне кажется, что это чаще разумно, чем нет. Если перечисляемый тип гоняется в число и обратно, пусть это всё в явном виде будет написано. А вдруг написан бред? Когда всё потенциально бредовое требуется в явном виде расписать, заметить бредовость легче.
OCTAGRAM
arc RAII objectiveC ada Delphi
ARC forbids Objective-C objects in structs or unions
А Objective-C, оказывается, не так крут, как я думал. Хотя, казалось бы, какие проблемы. Везде в других местах (и в C++ тоже) такое работает.
OCTAGRAM
контейнеры ada Delphi В обоих языках появились конструкции для удобного перебора коллекций. for-in-do в Делфи и for-of-loop в языке Ада. Но в языке Ада можно и нужно возвращать ссылочный тип, и под такой перебор не нужно объявлять переменную, а в Делфи — нужно, и нужно именно затем, что оно всё будет при переборе постоянно копироваться и уничтожаться, хоть там какой развесистый record внутри. Но зато при переборе стандартного System.Generics.Collections.TDictionary в Делфи перебираем пары ключ-значение, а при переборе стандартного Ada.Containers.Hashed_Maps — только сами значения.
OCTAGRAM
ada Delphi Заметил, что новые формы вызовов событий содержат const перед Sender: TObject. Действительно, ведь так оно и должно быть при ARC. В Делфи при работе со сложными структурами итого получается 4 режима передачи параметра: «» (ничего), «const», «var», «out». Им условно соответствуют адские режимы «» (ничего), «in», «in out», «out», но «» (ничего) — это на самом деле пропущенное указание режима «in», а делфёвому «» (ничего) нет прямого аналога. Режим «» (ничего) в Делфи — это когда вызывающий передаёт параметр, а вызываемый может его по своему усмотрению поменять. Всё бы хорошо, но для счётчика ссылок это не очень здорово, в большинстве случаев лишний раз зря тревожить, а это строки, COM-интерфейсы, массивы, да много всего. И повелось перед такими параметрами ставить в Делфи «const», а в силу лени — не ставить, где не надо. Пока не было ARC, для ссылок на объекты как раз было не надо, а теперь раз, и стало надо. В старом коде во всяких TNotifyEvent этого уже не поменять, и без того совместимость поломали знатно. Только в новых сигнатурах обработчиков получается писать как правильно.
OCTAGRAM
ada Delphi Взял для разнообразия новый проект. Вот никогда не фанател от упрощённого стиля Windows 10. В Мак ОС Десять до сих пор кажется эстетичной Аква, а безальтернативная упрощёнка — это что-то мимо. Но, поди ж ты, оказывается, это востребовано. Хотят в этом стиле. А ещё хотят, чтоб в этом стиле и на Семёрке работало. Всё указывает на выбор Делфи как инструмента реализации. Они там давно (кажется, в XE2) встроили стилизацию и научились мимикрировать под элементы управления, обычно наблюдаемые только в Метро. Решающий вклад тут вносит, что со времён Делфи 2006 возобновлена раздача базовой версии на шару. Без этого приходилось постоянно иметь дело с натленной Делфи Семь, как у легальных пользователей, так и у пиратов, и нового софта не появлялось, соответственно, интересных заказов — тоже.

По этому поводу получил возможность забуриться в свежий Делфи Токио. И сравнить с Адой. Первым делом зашёл в настройки проекта посмотреть, как там дела по умолчанию со включениям проверок времени выполнения. Негусто. Всё выключено. Никак видеокодеки опять пишем или на Розеттакоде секундами меряемся. Часы моего времени на отладку дороже, поэтому всё врубил. Во всяком случае, всё, что смог, а было там только три галочки. Но совсем как в Аде писать всё равно не получилось. Не хватило ещё проверки указателя на null-nil до того, как пытаться по нему пройти. На Аде я могу забуриться внутрь сложного JSON значения, а если где-то что-то не нашлось, вылететь по известному исключению в обработчик, который ничего не сделает. В Делфи, по крайней мере, в стандартной библиотеке, если не брать мои CVariants, такая история не работает. Ну или лучше не пользоваться. «X.Values['ObjectKey'] as TJSONString» запросто может оказаться nil, и если дальше у него получить Value, то вылетает исключение Access Violation с доступом к первым байтам виртуальной памяти. Чё-т как-то не очень такое ловить. Лучше б что-то языковое бросалось ДО попытки вызвать метод через такой указатель.

Освежил воспоминания, почему @akastargazer так радовался, что в Обероне не надо так париться управлением памятью. Как адаисту со стажем, мне это было не очень понятно, что там париться, и зачем решать эти проблемы таким изуверским способом, а тут вот оно всплыло. За каждый TJSONObject и TJSONPair трясёшься, чтоб он только не утёк, если на полпути исключение вылетит. Всё огораживаешь в try-finally-FreeAndNil-end, всем значениям, которые могли бы при прочих равных быть промежуточными, даёшь имя переменной. В GNATCOLL.JSON такого страха не было, и в моих делфёвых CVariants такого страха нет. Там RAII и счётчик ссылок внутри. Но столбовой дорогой это до сих пор не стало.
OCTAGRAM
embarcadero FMSoft Delphi uniGUI UniGUI Web App Development
Присмотрел на сайте Embarcadero семинар, который мне удобен по времени. Заранее поставил отметку «Пойду».
Start Date: Jun 22 2017 at 19:00
То есть, по универсальному времени это час ночи 23 июня, а по барнаульскому — 8 утра 23 июня. То есть, сейчас уже 10 минут как идёт. А куда заходить-то, алё?

На почте пусто, по ссылке пусто. У FMSoft или uniGUI каких-то Твиттеров не наблюдается как резервного средства оповещения. В официальных фейсбуке и твиттере Делфи про вебинар нет. Копец.
OCTAGRAM
ada Delphi Общая платформа исполнения приложений как последний шанс для Delphi и Ada
В обстановке, когда всякие разработчики нет-нет, да и «забудут» то про Delphi, то про Аду, Платформа — это соломинка, за которую делфистам и адаистам нужно ухватиться и держаться. Платформа предполагает целый комплекс мер по мотивации разработчиков использовать именно её, а не что-то другое. Тут и импортозамещение, и экспорт в сценарные языки программирования, более лёгкий, чем в SWIG, и многое другое, и попутно такие компоненты становятся доступны в Delphi и Ada с относительно удобным программным интерфейсом.
OCTAGRAM
com Centennial Windows10 WinRT Delphi Windows 10: From WinRT to Centennial with Marco Cantu; длительность 54 минуты
Ну вот, наконец, доклад по WinRT не от Microsoft, у которых, конечно, в их параллельной Вселенной всё без проблем, а как на самом деле, без мнения третьей стороны не понятно. Мне вообще наиболее интересна была бы связка Centennial+Islandwood, чтоб в вендор локе WinRT так уж сильно не увязнуть, но это с кондачка не поднять.
И да, то обновление, которое должно было быть в ноябре, не принесло поддержку Linux ARC, но поддержка Project Centennial там имеется, об этом и доклад. И это именно то, что сейчас можно скачать на шару.
OCTAGRAM
SOM Delphi Интеграция внешней объектной системы в Delphi на примере IBM SOM
Один из моих проектов реализует поддержку SOM в Delphi. Разработка начиналась на Delphi, пришлось часть привязок делать вручную и не так красиво, в процедурном стиле, без проверки типов. Используя эти привязки, был написан генератор привязок в объектном стиле, а затем и сам генератор был переписан на новые привязки, став подтверждением их работоспособности. Ради красоты пришлось хакнуть объектную систему Delphi, и, может быть, вам будет интересно, как это вообще можно делать.
OCTAGRAM
ООП SOM corba Delphi Раздраконил свой генератор привязок до такого состояния, что уже заработала программа, использующая исключительно новые привязки. Это пример для старых привязок, а это — для новых. В старых привязках SOMObject — это указатель на запись, а все остальные классы — синонимы SOMObject, то есть, контроля типов нет. В старых привязках, чтобы узнать тип аргумента, нужно было в процедурном стиле написать ParameterDef__get_type, а вот имя аргумента объявлялось в Contained, поэтому Contained__get_name, а так как вручную мне лень синонимы везде прописывать, то только по таким именам работало. В новых привязках генератор собирает все методы класса в одну общую кучу, и всё работает достаточно очевидным образом с вызовом методов через точку. И даже атрибуты CORBA спроецировались на свойства Delphi. Поскольку в Delphi жалкое одиночное наследование, генерить список методов требуется каждый раз сначала, и именно это и делается, зато потом удобно.

Работает это посредством того хака, что создаются объекты SOM, а Delphi думает, что это объекты Delphi. Так как с точки зрения Delphi методы статические, Delphi не лезет в VMT, делает статический вызов, в нём написан код, который направит вызов в SOM, и оно там пойдёт куда надо. Ещё немного пошаманил, чтобы волшебным образом работали классовые функции. Классовые функции могут вызываться как у объектов, и тогда Delphi пытается взять из объекта VMT по нулевому смещению, а может — непосредственно у класса, и тогда берётся статический адрес VMT. Учитывая, что с точки зрения Delphi классы друг от друга не наследуются, отличить эти случаи не сложно. Нужно просто сравнить Self со своим именем, и если да, то нас вызвали через имя класса, и класс-объект нужно искать одним способом, а если нет, то нас вызвали как метод объекта, и надо ещё раз разъименовать Self, и там будет лежать указатель на класс-объект.

Немного подкрутил, чтобы в результате метода SOMObject.somGetClass учитывался метакласс. Была мысль вообще все методы метакласса спроецировать на классовые функции и процедуры, но потом посмотрел, сколько там всего в SOMClass, и решил, что не надо. Тем более, что в SOM.IR публично показан только один метакласс, SOMMSingleInstance. Но даже ради него подкрутил, чтобы у метода SOMObject.somGetClass возвращался именно указанный метакласс, а не просто SOMClass. Кстати, так получается, что с точки зрения языковой проекции метаклассы не могут так просто наследоваться. То есть, умом-то мы понимаем, что компилятор SOM гарантирует совместимость метаклассов, но вот во что это спроецировать, открытый вопрос. Если мы наследуемся от двух классов с разными метаклассами, то метакласс потомка будет заведомо принадлежать пересечению множеств потомков каждого метакласса, и что, для этого динамически создаваемого метакласса тоже создавать привязки? А там по цепочке ещё для метаклассов более высокого порядка может потребоваться автоматическое создание. Одно дело — когда движок SOM это создаёт, и другое дело — когда генерится текст. Я решил, что этого делать не нужно, а раз так, то даже, если был класс A с указанием метакласса M_A, и от него наследуется класс B, то, если B не укажет явно тот же метакласс, что и A, в его привязках будет опять обычный SOMClass.

Естественно, все методы обычного TObject не будут работать. Я эту проблему пытаюсь решить, скрывая их при помощи reintroduce в private. Только операция as портит картину. Её не спрячешь, но хотя бы заменил методами, приводящими тип вверх и вниз. Вот так, с небольшой порцией магии создаётся впечатление, что SOM в Delphi как родная. Классы, методы, свойства.
OCTAGRAM
SOM corba Delphi В #2807187 я выяснил, что в Delphi самое сложное — это неразрывный блок type. Все отложенные определения типов к концу блока должны случиться. Поэтому (с точки зрения, где сложнее и рискованнее) поддержка SOM начинается с Delphi, а в самом проекте SOM-Delphi — с блока type. Вот, чего удалось добиться: SOMIRTest.DumpOut.pas. Компилятору Delphi сейчас не хватает только реализации методов, но это уже совсем другое дело. Это не блок type. Пока я тут прыгал с EF на IRF, у меня тут достаточно текстовых заготовок осталось, чтоб написать методы.

Что удалось выяснить: в доках было чётко написано:
For this reason, the use of the -u compiler flag requires that all of the types mentioned in the IDL source file must be fully defined within the scope of the compilation. Warning messages from the SOM Compiler about undefined types result in actual error messages when using the -u flag.
То есть, как раз то, что мне не оказалось неприемлемым в EF в купе с невозможностью обработать информацию из нескольких IDL за один проход. Однако, каким-то образом ссылки на отсутствующие классы всё же попали в SOM.IR, на той строке, куда я решёткой поставил ссылку.

Среди расширений CORBA TypeCode kind: внешние типы (tk_foreign), указатели (tk_pointer), циклические ссылки (rk_self). Удалось сделать такую эвристику, чтобы внешние типы по максимуму были определены не сами по себе, а только через указатель. Вот, например, Emitter Framework любит поработать с FILE* из VisualAge C++ RTL. Нашлись методы, которые «указательность» воплощают не через tk_pointer, а через режим аргумента in out, и заставляют алгоритм-таки объявить внешний тип явно. Там тоже немного подкрутил, в Delphi как раз есть синтаксис аргументов "var X" и "out Y" без указания типа. Из четырёх осталось два автоматом объявленных как явные указатели (somId и va_list), и так оно и есть в их случае.

Нашлись и недостатки по сравнению с EF. В EF есть комментарии, а в IRF — нет. Без комментариев уже доки не погенерить, например. Martin Iturbide, владельцу edm2.com, пригодилось бы, он у себя на wiki размещает. Ещё в EF все типы конкретно определены, а в IRF всё делается через CORBA TypeCode. Все пользовательские типы видны как объекты TypeDef, но потом, когда эти типы используются, в CORBA TypeCode видно только конечный результат с учётом всех подстановок. Сохраняются имена только у сложных типов, таких, как записи, перечисляемые и внешние типы, но они содержат не полный идентификатор, то есть, от корня, а просто имя, и его приходится эвристически разрешать, если хотим, чтобы всё было красиво, и эта эвристика, вообще говоря, заведомо менее надёжна. Таким образом, будет не лишне иметь эмиттер, работающий аналогично IR emitter, собирающий всё в одном месте, но просто побольше информации.
OCTAGRAM
VisualAge Delphi stdcall VisualAge C возвращает структуру CORBA Any из двух указателей в EDX:EAX, а Delphi считает, что надо через скрытый указатель действовать. Оба считают, что это stdcall.
Вообще, IBM, наверное, на все, какие только можно, грабли наступили в своём ABI:
Импорт/экспорт структур данных между DLL
cdecl varargs
Смешение cdecl и stdcall в одной библиотеке импорта для C
enum, которые внезапно оказались байтового размера
Теперь ещё структуры в результатах
OCTAGRAM
SOM Delphi SOMIRTest.DumpOut.pas
Ну вот, уже как-то повеселее пошло. Зря не начал сразу с SOM IR. Я тут подсчитал, с учётом крюка через Emitter Framework я вручную написал привязки для почти половины классов (37/75). Классы Emitter Framework чем-то похожи на Interface Repository. И там, и там есть модули (пространства имён), интерфейсы (классы), операции (методы), typedef, но в Interface Repository типы кодируются CORBA TypeCode с нехитрым сишным API, а в Emitter Framework под каждый struct, enum и sequence — отдельный класс. Пока нет генератора, привязывать классы получается дольше.
OCTAGRAM
unicode UTF-32 Delphi «Поддержка» четырёхбайтовых строк в Delphi реализована посредством объявления type UCS4Char = type LongWord; и type UCS4String = array of UCS4Char;
…а также функций для конвертации между WideString и UCS4String, а в юникодных Delphi — также между UnicodeString и UCS4String. Поскольку UCS4Char — это не символ, а замаскированное число, в теле программы такие литералы так просто не попишешь. Хотя, конечно, можно приводить тип постоянно. UCS4String — это вообще не строка, а динамический массив, и плюс на нём не сработает. Также для массивов не работает COW. Для строк Delphi автоматически добавляет в конец нулевые байты в нужном количестве на случай, если эту строку захотят послать в ущербные сишные API, вот она как раз бы и подошла сразу, а для динамического массива беззнаковых чисел такого делаться не будет, поэтому это делают функции конвертации. Соответственно, Length вернёт либо 0 для пустой строки, либо длину, на 1 большую настоящей длины. Так что даже если вдруг для динамических массивов заработает плюс, он будет косячить. В array of const и Variant, я так понимаю, UCS4String тоже просто так не влезет.

Но больше всего у меня горит от того, что в неюникодных Delphi функции конвертации поддерживают только BMP. Семёрка, похоже, если и сдохнет, то только со всеми Delphi вообще. Embarcadero так и не приложили усилий, чтобы это могло быть иначе.
OCTAGRAM
indy Delphi Поделал веб–сервер на Delphi 7 и Indy. URL–декодеры норовят сконвертить текст в свой долбаный ANSI и завопросить всё нафиг. Юникодных аналогов StrReplace нет, приходится конвертить в UTF8 и обратно. Коннектор к базе данных, как выясняется, тоже конвертит всё в ANSI и вопросит всё нафиг.

Заказчик хотел возможность копипастить код из обычного приложения в web. Решил это тем, что сделал пул из Data Module. Каждый Data Module содержит все соединения к базе данных, отправлялки e-mail и прочие компонентики, скопипащенные из обычного. Для каждого запроса берётся экземпляр этого Data Module, и в нём запускается специальный метод, который все эти компонентики теперь может использовать. Опасался, что из неосновного потока что–нибудь будет работать неправильно, но вроде полёт нормальный.

Вот так понимаешь, насколько хорош AWS. В нём просто нет этих перекодировок, неожиданно происходящих то тут, то там. Да и зоопарк из String, Wide_String, Wide_Wide_String, Unbounded_String, Unbounded_Wide_String, Unbounded_Wide_Wide_String в стандартной библиотеке, оказывается, не так уж плох. Можем работать со строками с любой шириной символа, не будучи вынужденными перекодировать их в UTF-8. По крайней мере, самые базовые операции всегда есть. И библиотеки многие либо работают с последовательностями байтов, либо с юникодом, который появился достаточно давно, в Ada 95 и был в GNAT изначально. Не париться про существование ANSI несколько проще, хотя и всё ещё не так просто, как в node.js, когда console.log() без дополнительных танцев с бубном просто выводит Юникод на любой OS.
unfalse
говно Delphi Сергей Терлецкий, менеджер по работе с образовательными учреждениями в компании Embarcadero.
Наша компания постоянно мониторит рынок и опрашивает профессиональных разработчиков, чтобы развивать наши продукты в востребованных направлениях. Будущий тренд – это связь облачных технологий, мобильных приложений и интернет вещей. Особенно будет востребована кроссплатформенная разработка и создание связанных приложений. Попробуйте RAD Studio XE7.

Конечно, что же ещё ему советовать? tproger.ru
OCTAGRAM
pascal Delphi Тут в LinkedIn хвастаются, что Delphi Seattle продано 1,3 миллионов. Удивительно, как с их системой лицензирования так мало пиратят
OCTAGRAM
com IDL Delphi Using Object Pascal or RIDL Syntax
Наткнулся как–то на сравнение синтаксисов IDL в Delphi, но не смог докопаться, а как работать с паскалевским–то, ведь Delphi моего патриотизма не оценила и показывала только RIDL. Оказывается, даже в XE2 его нету, в документации к Seattle, наверное, забыли убрать, зато в древней Delphi 2007 можно зайти в Tools » Options » Environment Options » Delphi Options » Type Library, переключить Language в Pascal, после этого обычным File » Open… открыть .tlb и переключиться на вкладку Text.

Понадобилось поизучать одну библиотечку без документации, ибо эта библиотечка может потенциально помочь мне поддерживать бинарные форматы, в которых ВУЗы обязаны посылать сведения в РосОбрНадзор. А библиотечка муторная, и в синтаксисе IDL у меня глаза начинают вытекать, вот я и вернулся к этому вопросу и–таки получил её в паскале–подобном синтаксисе.

Можно посмотреть здесь: 1, 2

С документацией на формат XML дела тоже не заладились. Когда–то документацию можно было скачать с сайта госконторы, которая этот формат и делала, а сейчас на её сайте какая–то хрень, и ничего не найти. И на сайте, куда переехал программный пакет GosInsp, тоже не видать.
OCTAGRAM
ada Delphi Выполнил не так давно проект на Ada, теперь на Delphi пишу. Вот что чувствуется, так это то, что в Delphi тоже есть раннее объявление типов, но полностью объявлен тип должен быть в том же блоке type. Нельзя разорвать этот блок константами или процедурами. Приходится всё перетасовывать.
В Ada каждое объявление типа, подтипа, переменной или константы — отдельный элемент, там просто разрывать нечего.
OCTAGRAM
SOM WinRT ada Delphi Project Centennial: Converting your Normal Windows App (Ada, Delphi, SOM) to a Metro Windows App for Distribution in the Windows Store
В Microsoft наконец зачесались, а чёй–то так мало приложений под Metro, наверное, средства разработки были трешовые, значит, надо дать возможность нормальными средствами разработки делать приложения для Metro
OCTAGRAM
Win10 Delphi IAccessible2 Тестируем IAccessible2, задачка — узнать, какое слово сейчас под курсором, например, в Firefox. На Windows 2003 реализация пашет замечательно, на Windows 7, как передаёт заказчик, тоже, а вот на Windows 10 нифига. Service provider у client area окна Firefox (IceDragon в моём случае) не хочет отдавать IAccessible2 интерфейс. И объект, возвращаемый AccessibleObjectFromPoint, тоже не приводится к интерфейсу IAccessible2.
Я грешу на то, что, наверное, uiAccess нужно включить и подпись цифровую сделать. Пожалел, что своевременно не озаботился попросить ключик для цифровой подписи для open source разработчиков, так бы быстро проверил.
OCTAGRAM
C++ Delphi Немного про странноватых менеджеров, которые хотят переписать на C++
A new project manager at my company asserts that Delphi can not be used in an FDA approved medical device. Has anyone heard of such a thing; do you have an contra evidence ? He assert the same for Windows Embedded, Linux and C++ is what it must be.

I don't think he has a basis, other than C++ programmer's distain and disrespect for Delphi plus the desire to do things the way he has done in the past. The Devices are Class 1, with no chance of patient harm. Problem is we have a large code base, developed over 15 years, that according to the project manager must be ported to C++ (at the risk of breaking the bank).
Your comments that "never been raised as an issue" is what I have heard from others, regulators don't care what language the software is written in.
Thanks for your comments; I'm not sure if I will continue to fight the anti-Delphi biases.

Matt, thanks for your testimonial. I'll add it to my bucket of evidence.
The 2nd reason my PM says we MUST port to C++ is the difficulty of finding Delphi programmers. There is a grain of truth perhaps to that, but I don't think it should be elevated to a reason to risk the company by undertaking a costly port to C++.

The argument about C++ programmers being more prevalent may be valid (there are other threads that discuss this), but if for the sake of argument we assume that it's true, then his argument is about the tradeoff for the perceived safety of a larger body of programmers at a cost of longer development and debug times. It also harkens back to the old saying (pre-PC days) "No one ever got fired for buying IBM". Your manager may be a CYA type. So it goes.

The previous product suffered a rewrite into C++ and never came back to life, and still sits in a pile on the floor. One would think people would not repeat the same mistake, but that CEO and PM were fired because of the failure and the new ones have big egos and don't want to hear about history. Go Figure.
OCTAGRAM
GEMA icon ada Delphi bitbucket.org

Году так в 2009м исходя из той картины мира, которой я тогда руководствовался, я считал, что на языке Ада будет здорово писать, если будет полное WinAPI, чтоб и ACL поманипулировать, и оконными сессиями, и в пространство объектов NT забраться можно было. Win32Ada оставляли желать лучшего по охвату современного API. Делать я это намеревался не через сишные заголовки, в которых часть метаинформации безнадёжно потеряна, а вкрутив мозги джедаям. То есть, есть группа JEDI, которая делает неплохие привязки, но вот одна проблема, они это делают для Delphi, а не для Ada. Так как языки похожи, неплохо бы одно в другое сконвертировать, причём, по возможности, автоматом, и не AST в AST, а текст в текст.

Поначалу я пытался наладить конвертацию на препроцессоре GEMA, даже получилось, но это было явно больше, чем на что был расчитан GEMA, да и писать тяжело. Чем более зрелую реализацию пытаешься сделать, тем в большее количество ограничений упираешься. Для тех, кто не знает, там какое–то продвинутое программирование начинает становиться похожим на продвинутое программирование в bash. То есть, мы не можем сделать переменную x ассоциативным массивом, зато можем понаплодить переменных x[*], и работать дальше как будто у нас есть ассоциативный массив.

Решил поискать альтернативу. Смотрел в сторону GPP. Смотрел в сторону Refal. Как остановился на Icon, уже точно и не помню. Примерные соображения таковы, что когда–то раньше мне было интересно, чтобы «for а := 1 to 3 do B;» было не единым узлом синтаксического дерева, а чтоб 1 to 3 сам по себе что–то значил, присваивание было бы таким же присваиванием, как и в других местах, и for мог перебирать не только это, но и другие выражения, и как–то так получилось, что такой язык действительно есть, и так как он по описанию хорошо подходит для обработки текста, и в нём есть backtracking, его и решил взять. Так я и начал писать на Icon. Начало не из лёгких. Одно дело переписать что–нибудь с одного императивного языка на другой (а на Icon можно писать в императивном стиле). Другое дело — нужно было переписать шаблоны. На GEMA уже кое–что было написано, упирающееся в ограничения GEMA, надо было разобраться в Icon и переписать на него. Долго мучился, пока не начал думать «в две стороны». В Icon каждое выражение — это генератор, и функции — это тоже генератор, и особенно важно научиться писать функции, которые не обычные функции, как в императивном языке программирования, а пробуют распознать текст по шаблону и переписать в другой текст, и сами при этом такие же, как они, преобразователи для своей работы используют. Чтобы их писать, надо думать в две стороны: что случится, если выполнение идёт вперёд, и что случится, если начнётся откат.

Переписал. И пошёл дальше этим путём, насколько смог. Времена у меня были не из лёгких, 2005-2010 года самые паршивые в жизни получились, да и сейчас до сих пор не сахар. Довёл до такого состояния:

bitbucket.org
bitbucket.org

У меня на сайте написано:
Хочу как вот этот парень (Л. Поттеринг), и есть идеи, чем бы я мог заняться, а получается так, что мой поезд жизни едет и едет по своим рельсам, а мне только и остаётся, что жадно смотреть в окно.

Это как раз тот случай. «Посмотрел в окно» — и дальше по своим рельсам. Специальность у меня приборостроитель, диплом придётся на левую тему делать, совместить образование с учёбой в очередной раз не получается. Сейчас бы я, впрочем, за кое–что другое взялся.

Когда я пишу про то, чтобы взять Cocoa и GNUStep и сделать мост в SOM, а потом, может быть, и сам GNUStep переделать, это для меня выглядит вполне посильно. Есть BridgeSupport XML, есть опыт преобразования текст=>текст (в том числе #1435793). Самые разые способы достигать этих целей.
OCTAGRAM
SOM ada bpl Delphi Есть в Delphi и Ada приятная плюшка, собирать несколько пакетов в динамические библиотеки для совместного использования (.bpl в Delphi). Приятно это тем, что всё прозрачно. Вчера собирал всё статически, завтра решил, что вот этот, этот и вот этот пакеты должны быть отдельно в другой динамической библиотеке, и это вынесение происходит без лишних изменений кода. Не приходится вставлять макросы типа «если объект динамической компоновки в этом проходе такой–то, то экспортируем эту функцию, иначе импортируем её». Но вот есть ещё SOM, который решает проблему хрупкого базового класса и другие аналогичные проблемы, которые возникают хоть в C++ библиотеках, хоть в .bpl, они в этом плане не отличаются. Если делать SOM эмиттеры для Delphi и Ada, лучше с самого начала предусмотреть ситуацию, когда .bpl и SOM .dll применяются одновременно, так как хрупкость .bpl может нивелировать преимущества SOM. То есть, допустим, реализован у нас какой–то SOM класс в каком–то юните, который попал в какой–то .bpl и оттуда переэкспортируется в .dll, откуда может быть использован SOM потребителями. А юниты, соседствующие с юнитом SOM класса внутри .bpl, конечно, будут искать структуры ClassData не через .dll, а обращаться напрямую в юнит. Кроме того, так могут поступать и юниты из соседних .bpl. И тут может быть такая проблема, что интерфейс SOM класса мы поменяли, и SOM это изменение поддерживает, вот только интерфейс .bpl изменился, и это изменение может сломать весь код, который ходил в структуры ClassData через .bpl в обход SOM. С другой стороны, если попытаться это исправить наивным способом, то даже .bpl будет ходить в свой собственный класс через .dll, что не должно происходить. Пока я решение вижу в том, чтобы отрезать все меж–.bpl'ные связи между компонентами, которые собираются независимо. То есть, если у нас скрипт собирает 3 .bpl синхронно, между ними связь разрешена, иначе нужно ходить через .dll. Теперь надо подумать, как это лучше сделать. В реализации CORBA для Delphi, например, делается три разных юнита с разными суффиксами для каждого класса, один для импорта, второй для экспорта, и ещё третий для чего–то. Но CORBA клиент и сервер обычно живут в разных процессах, а SOM — это внутрипроцессная CORBA. В моём случае юнитов, импортирующих одно и то же, будет столько же, сколько и независимо собираемых компонентов. Вплоть до того, что у каждого, получается, должно быть своё видение SOM API. Либо будет NoBPL версия, которую нельзя заворачивать в .bpl, а для .bpl нужно автоматизировать клонирование импортирующих юнитов в другое пространство имён. То есть из SOM.pas делается Baz.SOM.pas, из SOM.ClassManager.pas делается Baz.SOM.ClassManager.pas, и uses у них внутри переписываются. Либо надо посмотреть, можно ли включить юнит внутрь .bpl, но чтоб он наружу не светился, тогда этого делать не придётся. У всех независимо собираемых компонент будет свой взгляд на мир за счёт статического включения импортирующих юнитов, но не придётся называть эти юниты по–разному.