Обожаю, что вся сишная часть встраивания Tcl помещается на открытку. Tcl_CreateInterp, потом скрипт через Tcl_EvalEx или Tcl_EvalObjEx, ответ через Tcl_GetObjResult. Всё, что пересекает границу, это строка, а строка единственный тип, о котором обе стороны уже договорились!
Ну, почти. Tcl_Obj хранит строковое представление и, если значение уже использовали как что-то другое, ещё и внутреннее. Используйте одно и то же значение в одном месте как список, а в следующем как число, и каждое использование выбрасывает чужое внутреннее представление и заново строит своё из строки. Это называется shimmering, и его не видно, пока он не всплывёт в профиле.
Ещё одна вещь, которая не пересекает границу, это поток. Интерпретатор принадлежит потоку, который его создал, так что хост не может просто так вызывать его из пула рабочих потоков. (Хост-программы забывают об этом удивительно быстро.)
Так что же переходит, кроме имени функции? Текст, кеш того, что этот текст значил в прошлый раз, и принадлежность потоку. Две вещи из трёх легко упустить.