о библиотеках (программистское)
Jan. 31st, 2007 11:38 pmНижеследующее будет интересно только программистам.
Время от времени, когда мне приходится сталкиваться с тем, как в Перле или других похожих языках устроен интерфейс с библиотеками (shared libraries - .so на юниксах и DLL на Windows), их безумие меня раздражает. В Перле, например, вся система XS для написания расширений на C - одно сплошное упражнение в прикладном мазохизме.
Как правило, приходится писать на C с использованием кучи заголовков и макросов данного языка; потом все это компилируется в shared library, которую может загрузить программа на данном языке во время выполнения, динамически. Зачастую перед компиляцией нужно еще исходники пропустить через специальный препроцессор для данного языка или данной интерфейсной библиотеки (см. SWIG), у этого препроцессора есть свой синтаксис, который нужно помнить, итд. Иногда все это выглядит очень просто - например, модуль Inline в Перле позволяет вызывать код на C прямо так, без казалось бы всякого клея, оно берет и работает - но на самом деле там за кулисами происходит, во время исполнения, создание XS-модуля, компиляция его, и кэширование результата.
Главное, что остается непонятным - зачем вообще нужно что-то компилировать. Мы хотим загрузить файл foobar.dll, в котором есть функция foo(), и после этого вызвать ее из нашего относительно-динамического языка. Мы знаем ее прототип. Мы знаем соглашение вызова (calling convention), которое она использует. У нас есть вся информация, чтобы прямо во время исполнения сконструировать правильный вызов к этой функции. Нам не нужен компилятор C, чтобы сделать эту работу для нас. Да, конечно, с компилятором в целом проще и выглядит надежнее, но какой же это, с другой стороны, overkill; и необходимость правильной трансляции между типами нашего языка и типами C приводит к необходимости использовать ужасные препроцессоры, макросы, и прочую дрянь.
Большинство функций, которые мы хотим вызвать таким образом - простые. Они получают в качестве аргументов такие простые вещи, как int или char* и возвращают то же. ( Read more... )