вызывая TCL C API внутри процедур пакета tcl - PullRequest
0 голосов
/ 24 августа 2018

Я использую TCL-C API для своей программы.
и я прочитал и создал тестовую программу, которая похожа на этот C ++ пример .
Но у меня проблема с этим примером. когда я использую этот пример в оболочке (загружая его с помощью load example.o), каждый ввод автоматически вызывает интерпретатор API и запускает команду, связанную со строкой ввода.
Но предположим, что я хочу, чтобы ввод вызывал процедуру tcl, которая находится внутри требуемого мной пакета, эта процедура проверит параметры и напечатает другое сообщение, и только после этого вызовет функцию, связанную с API TCL-C (вид оболочки), В таком случае как я могу это сделать?
Я где-то читал, что символ @ - это символ, который должен использоваться для вызова внешней программы, но я просто не могу найти, где он был.
Я приведу небольшой пример, чтобы прояснить ситуацию.

somepackage.tcl

proc dosomething { arg1 , arg2 , arg3 } {
   # check args here #
   set temp [ #invoke here TCL-C API function and set it's result in temp ]
   return $temp
}

package provide ::somepackage 1.0  

test.tcl

package require ::somepackage 1.0
load somefile.o   # this is the object file which implements TCL-C API commands [doSomething 1 2 3 ]
...

1 Ответ

0 голосов
/ 25 августа 2018

Но у меня проблема с этим примером.когда я использую этот пример в оболочке (загружая его с помощью load example.o), каждый ввод автоматически вызывает интерпретатор API и запускает команду, связанную со строкой ввода.

При условии, чтофрагменты сценариев точно представляют вашу фактическую реализацию, тогда проблема в том, что ваш Tcl proc с именем doSomething заменяется командой Tcl, реализованной на языке C, когда ваше расширение load ed.Процедуры и команды находятся в одном и том же пространстве имен.Когда порядок загрузки будет изменен, проблема останется прежней.

Я прочитал, что все проверяется интерпретатором tcl, поэтому в этом случае я должен назвать имя tcl функций обтекания C вспециальный способ, например, cFunc.Но я не уверен в этом.

Это правильно.Вы должны организовать команды, реализованные в C, и их скриптовые оболочки так, чтобы их имена не конфликтовали друг с другом.Некоторые (базовые) параметры:

  • Использование двух разных пространств имен Tcl с одноименными процедурами
  • Применение некоторых соглашений об именах к процедурам и командам-оберткам (ваша cFunc подсказка)
  • Если ваш API был предоставлен как фактические объекты Itcl или TclOO, а отдельные команды были методами, вы могли бы использовать подкласс или миксин для размещения уточнений (используя супер-ссылку, такую ​​как next в TclOO, дляперешли от уточнения по сценарию к реализациям на C).

Решением оперативного исправления в вашей текущей установке, которое лучше заменить каким-либо реальным проектом, было бы rename или interp hideконфликтующие команды:

  1. load somefile.o
  2. Скрыть доступные сейчас команды: interp hide {} doSomething
  3. Определить скрипт-обертку, вызывая в какой-то момент скрытый оригинал:

Например:

proc doSomething {args} {
  # argument checking
  set temp [interp invokehidden {} doSomething {*}$args]
  # result checking
  return $temp
}
...