Как разработать инструмент на C / C ++, командный интерфейс которого - оболочка Tcl? - PullRequest
0 голосов
/ 17 июня 2019

Предположим, что необходимо разработать инструмент X, написанный на C / C ++ и имеющий командный интерфейс Tcl, каковы будут шаги или путь?

Я знаю о Tcl C API, который можно использовать для расширения Tcl путемнаписать расширение C для него.

Ответы [ 2 ]

2 голосов
/ 17 июня 2019

Что вы хотите сделать, это встраивание Tcl (полностью поддерживаемый сценарий использования; Tcl помнит, что это библиотека C), но все еще делает что-то вроде tclsh. Самый простой способ сделать это:

Получите копию tclAppInit.c (например, this является текущей в дереве исходных текстов Tcl 8.6, когда я пишу это) и адаптируйте ее, возможно, поместив код для регистрации ваших дополнительных команд, связанные переменные и т. д. в функции Tcl_AppInit(); Вы, вероятно, можете просто обрезать кучу вещей. Затем создайте и создайте ссылку непосредственно на библиотеку Tcl ( без заглушек), чтобы эффективно получить собственный настраиваемый tclsh с дополнительными функциями.

Вы можете использовать API Tcl более широко, если вы не заинтересованы в интерактивном использовании. Ядро для неинтерактивного использования:

// IMPORTANT: Initialises the Tcl library internals!
Tcl_FindExecutable(argv[0]);

Tcl_Interp *interp = Tcl_CreateInterp();
// Register your custom stuff here

int code = Tcl_Eval(interp, "your script");
// Or Tcl_EvalFile(interp, "yourScriptFile.tcl");

const char *result = Tcl_GetStringResult(interp);
if (code == TCL_ERROR) {
    // Really good idea to print out error messages
    fprintf(stderr, "ERROR: %s\n", result);
    // Probably a good idea to print error traces too; easier from in Tcl
    Tcl_Eval(interp, "puts stderr $errorInfo");
    exit(1);
}

// Print a non-empty result
if (result[0]) {
    printf("%s\n", result);
}

Это все, что вам нужно, если вы не используете интерактивное использование, и именно тогда Tcl_Main() становится действительно полезным (он обрабатывает довольно много лишних подробностей), который пример tclAppInit.c (упомянутый выше) показывает, как использовать .

2 голосов
/ 17 июня 2019

Обычно SWIG (Упрощенная Обертка и Генератор Интерфейса) - это путь. SWIG HOMEPAGE

Таким образом, вы можете написать код на C / C ++ и определить, какой интерфейс вы хотите предоставить.

Предположим, у вас есть некоторые функции C, к которым вы хотите добавитьTcl:

/* File : example.c */

 #include <time.h>
 double My_variable = 3.0;

 int fact(int n) {
     if (n <= 1) return 1;
     else return n*fact(n-1);
 }

 int my_mod(int x, int y) {
     return (x%y);
 }

 char *get_time()
 {
     time_t ltime;
     time(&ltime);
     return ctime(&ltime);
 }

Теперь, чтобы добавить эти файлы на ваш любимый язык, вам нужно написать «файл интерфейса», который является входом для SWIG.Файл интерфейса для этих функций C может выглядеть следующим образом:

 /* example.i */
 %module example
 %{
 /* Put header files here or function declarations like below */
 extern double My_variable;
 extern int fact(int n);
 extern int my_mod(int x, int y);
 extern char *get_time();
 %}

 extern double My_variable;
 extern int fact(int n);
 extern int my_mod(int x, int y);
 extern char *get_time();

В командной строке UNIX введите следующее:

 unix % swig -tcl example.i
 unix % gcc -fpic -c example.c example_wrap.c \
        -I/usr/local/include 
 unix % gcc -shared example.o example_wrap.o -o example.so
 unix % tclsh
 % load ./example.so example
 % puts $My_variable
 3.0
 % fact 5
 120
 % my_mod 7 3
 1
 % get_time
 Sun Feb 11 23:01:07 2018

Команда swig создает файл example_wrap.c, который долженбыть скомпилированы и связаны с остальной частью программы.В этом случае мы создали динамически загружаемое расширение, которое можно загрузить в интерпретатор Tcl с помощью команды load.

Взято из http://www.swig.org/tutorial.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...