Модули всегда source
d.Включение в них загружаемой библиотеки также требует некоторых хитростей.Вот один из способов.Создайте скрипт Tcl следующим образом:
apply {{scriptname realname} {
set script [open $scriptname]
chan configure $script -eofchar \x1a
chan read $script
chan configure $script -translation binary
chan seek $script 1 current; # Reset EOF state and skip past the EOF character
set f [file tempfile filename $realname.so]
chan copy $script $f
chan close $f
chan close $script
tailcall load $filename $realname; # Used to find the _Init function
}} [info script] YourRealLibraryName
Объедините его с ASCII EOF char ( Ctrl + Z ), а затем объедините вашу реальную разделяемую библиотеку в концепосле этого сохраняем все как файл модуля.Когда сценарий получен, он скопирует библиотеку с самого конца во временный файл и загрузит его из него.
Это зависит от того факта, что source
всегда настраивает используемый каналпрочитать сценарий, чтобы использовать символ EOF в качестве маркера конца файла, даже в системах, в которых он обычно не используется.Затем вы можете прочитать это и извлечь из него любые полезные данные.Конкатенация загружаемой библиотеки в конце тривиальна, но ее нужно извлечь в другом месте, чтобы фактически вставить в load
.Внутри все загрузка динамических библиотек в Tcl проходит через load
;это единственная команда, которая знает, как это сделать.Мы просто готовим способ для этого (и реальные файлы требуются по умолчанию, поскольку мы делегируем фактическую загрузку вызовам библиотеки операционной системы, которые выполняют эту работу; file tempfile
идеально подходит для этой работы!).Наконец, в конце мы обертываем все в apply
и tailcall load
, так что мы убираем все механизмы манипулирования именами аккуратно.
Возможны более сложные подходы с использованием виртуальных файловых систем, но нужно сделать гораздо большебольше кода, чтобы объяснить.Они все еще делают подобные вещи, но с хитростью, скрытой от глаз.