«Пурген»

«Пурген» — ещё один препарат-мем, вроде «нафталина», который я встречал только в присказках. Разумеется на уроках химии мы все его использовали в качестве индикатора присутствия щёлочи (только под другим названием — «фенолфталеин»), но я никогда не держал в руках пачку лекарства, где было бы написано «Пурген».

В СССР «Пурген» использовали, кстати, не только как слабительное — девочки смешивали его с канцелярским клеем (от чего он становился цвета фуксии) и красили им ногти, а мальчики делали «невидимые чернила», которые проявлялись от контакта с лимонным соком или тем же канцелярским клеем.

Реклама слабительного средства «Purgen Dr. Bayer»: «Идеальное слабительное средство», цена коробки 65 коп., оригинальные коробки снабжены синей бандеролью с русской надписью.
Дореволюционная реклама «Пургена», слабительного средства компании «Доктор Байер» (Будапешт)

И вот, на одном из чердаков, среди обрывков других бумаг, нашёлся клочок с рекламой «Пургена» компании «Доктор Байер». Сохранность была похуже, чем вы сейчас видите — пришлось дорисовать нейросетями рамку слева и сверху.

Почтовый штемпель с гербом и надписью «KÖZLEKEDÉSI MINISZTÉRIUM» и рукописная надпись «Dr. Baya és Társa» на бумаге
Подпись владельца компании на бумагах на «Пурген», 1908 год

Я было подумал, что производитель, упомянутый тут, — известная сейчас компания «Байер» (поэтому его и взял), но нагуглил более полную версию рекламы:

Никуда негодную поддѣлку и фальсификаты содержатъ всѣ тѣ коробки, которыя не снабжены синей бандеролью съ русской надписью и на которыхъ внизу на крышкѣ не помѣщена фирма Dr. Bayer és Társa Budapest. Коробка 65 коп., во всѣхъ аптекахъ.

Компанией «Dr. Bayer és Társa Budapest» (с венгерского «Доктор Байер и партнёр, Будапешт») управляли, по всей видимости, довольно известные в то время у себя на родине фармацевты — сначала Анталь Байер, потом его сын — Анталь Байер-младший. Предприятие владело несколькими патентами, завоевало медали на лондонских, парижских и будапештских международных фармацевтических выставках, а так же, по утверждению венгерской «Википедии», первым вывело на рынок лекарственные препараты в ампулах.

Оставить комментарий

FFI: баг не будет исправлен?

В пхпешном FFI есть баг — можно, вызывав сишную функцию случайно изменить значение совершенно других переменных

Очень не хочется это признавать, но похоже тот баг, который я обнаружил в реализации FFI (интерфейса к языку Си) в ПХП, исправлен не будет. Собственно, на это мне давно указал один из читателей в комментариях к прошлой заметке на эту тему, но мне всё не верилось.

В тикете, который я завёл по проблеме, один из разработчиков языка написал, что придерживается мысли, что это преднамеренное проектное решение. Не думаю, что это действительно так, наверняка получилось случайно, но как всё поправить, не снизив существенно производительность модуля FFI, — неясно.

Видимо, придётся жить с тем, что есть.

В прошлый раз, в качестве временной меры, я предлагал использовать str_repeat (или эквивалент) для того, чтобы разорвать запутанность двух переменных и таким образом предотвратить неожиданное их изменение. Это плохой приём, но я его задумывал в качестве временной меры.

Но раз это навсегда, давайте избегать сторонние эффекты правильно. Тот же читатель предлагает более корректный способ:

Первый параметр memcpy должен быть указателем на отдельно выделенную память достаточного размера. И в FFI есть метод для выделения памяти: FFI::new. Его и надо использовать вместо str_repeat.

Таким образом правильная работа с указателями должна выглядеть примерно вот так:

function memcpy(?string &$dst, string $src):void
{
    $len = strlen($src);
    // изготавливаем тип, в котором уместится копируемая строка
    $type = FFI::arrayType(FFI::type('char'), [$len]);
    // выделяем место под изготовленный тип
    $destination = FFI::new($type);

    FFI::cdef('char *memcpy(char *dst, const char *src, size_t len);')
       ->memcpy($destination, $src, $len);
    // преобразуем область памяти в строку
    $dst = FFI::string($destination, $len);
}

$rock = "ROCK";
var_dump($rock); // «ROCK»
memcpy($rock, "SOCK");
var_dump($rock); // «SOCK»

Что тут происходит?

Мы хотим вызвать сишную функцию для копирования одной строки в другую. В месте, куда мы собираемся копировать, должно быть выделено достаточное количество памяти, мы её выделяем методом FFI::new, передавая ему на вход специально изготовленный тип — указатель на массив однобайтовых символов длиной c копируемую строку.

После копирования преобразуем область памяти в пхпешную строку. Память, выделенная при помощи FFI::new, освободится автоматически.

6 комментариев