2013-06-16 4 views
0

Контекст Я хочу вызвать обратный вызов Tcl через SWIG из C/C++. Что еще более важно, я хочу, чтобы это было закрытием.Tcl обратный вызов из C/C++ с помощью SWIG

Предварительные знания http://computer-programming-forum.com/57-tcl/4481cebe0f09966d.htm (нет это не меня, только единственное, что, казалось, достаточно похожи, в поиске Google)

С Python, я создаю объект на стороне Python, дать ему __call__, запустите его через SWIG как PyObject *, и он все еще имеет доступ к нелокальным переменным, закодированным в Python (с небольшим количеством кода клейма), потому что он все еще тесно связан с интерпретатором, в котором он был создан.

Мое понимание (исправьте меня здесь) В Tcl единственный способ, которым я вызываю функцию из C, - через новый интерпретатор, передавая строку, представляющую команду (но ... тогда где закрытие ...?). Если я вызываю C/C++ из Tcl, все равно имею ту же проблему, потому что C/C++ не знает о вызывающем Tcl-интерпретаторе.

Annnnddd ... документация (http://www.tcl.tk/man/tcl8.6/TclLib/contents.htm), в то время как обширная, ... очень обширная. Коллективные знания, пожалуйста, спаси меня от моего невежества.

Вопрос Как получить замыкание/изменить, какое значение имеет имя в Tcl, указывающее на C/C++? Или даже просто получить дескриптор интерпретатора, который звонит в код C/C++ ...?

+0

Я пытаюсь понять, к какому шаблону вызовов вы пытаетесь. Вы хотите создать команду Tcl, которая вызовет какое-то закрытие на стороне C++ при вызове? –

+0

И Tcl не делает замыканий (и неудобно исправлять из-за природы значений в Tcl, язык на самом деле использует неизменяемые ссылки). Он выполняет сопрограммы и классы в 8.6, но они _named_ сущностей; подлинные ценности не могут работать таким образом. –

+0

На первый комментарий: да. Второй комментарий, h'okay, редактирование/вопрос. – user

ответ

0

Понимать во всем этом, что реализация Tcl является очень C-библиотекой, и поэтому имеет C способов делать что-то, а не C++. Это может сделать

Что вы хотите, это положить C++-закрытие как поле в struct, которое вы назначаете new. Затем вы набрасываете указатель на struct как аргумент ClientData на Tcl_CreateCommand; когда команда вызывается, вы вернете этот указатель в качестве одного из аргументов функции обратного вызова, после чего вы можете вернуть его к реальному типу и затем вызвать. Когда команда удаляется, вы получаете еще один обратный вызов (если вы его запрашиваете), и это отличное время до delete выделенное struct. Это звучит как много работы, но на самом деле это не так.

Я не знаю точно, как связать это с хорошим SWIGgable-подходом, поскольку я не использую ни SWIG, ни C++ в своем собственном производственном коде. Может быть, положить закрытие в нормальный объект, а затем SWIG? Однако под крышками это должно произойти. (К сожалению, тип прикладов - reinterpret_cast<…>. ClientData - это просто псевдоним для void * - если вы не используете древнюю версию Tcl с древним компилятором - вместе с обещанием, что код библиотеки Tcl не будет вытолкнут внутри в любом случае.) Я рекомендую использовать struct, потому что все пространство, в котором вы должны повесить вещи, - это просто ширина машинного указателя. Более того, вы можете, возможно, обернуть все в класс, чтобы скрыть детали gory, но я не могу вам помочь, поскольку я не являюсь гуру C++.

+0

От C это легко. Поместите указатель в «ClientData», и все готово. –

+0

H'okay, поэтому ... Я создаю команду для извлечения из команды Tcl. Я создаю эту команду в интерпретаторе, который регистрирует обратный вызов с моим расширением (но как мне заставить интерпретатор вызывать меня, если я являюсь расширением/Tclsh, является «хостом»?). Эта команда вызывается, и она возвращает мне имя некоторого обратного вызова (который предположительно может мутировать имена ... если у меня есть дескриптор интерпретатора хоста). Все это кажется условным, когда я получаю дескриптор интерпретатора хоста, о котором подробно не сообщают документы Tcl. Что? – user

+0

@Atash Если ваш код находится в общей библиотеке, которую вы хотите включить в интерпретатор Tcl, начните с [страницы Wiki для загрузки] (http://wiki.tcl.tk/1208) и убедитесь, что вы смотрите на «дискуссионных» частях. Идя в другом направлении, вы встраиваете Tcl и применяете другой набор правил (например, вам нужно заботиться об инициализации библиотеки). –

Смежные вопросы