SWIG генерирует TCL-обёртки с произвольным количеством аргументов - PullRequest
0 голосов
/ 16 февраля 2012

Я использую SWIG для генерации кода-обертки для вызова функций C ++ из TCL.Мой файл .i содержит только следующее:

%module baseFunc

%{
#include "tclFunctions.cpp"
%}

%include "tclFunctions.h"

Заголовочный файл - это, по сути, десятки этих объявлений:

static signed int some_function(const char * argN=NULL); //Maybe more arguments

Хотя все функции C ++ имеют фиксированное количество аргументов, вызовыиз TCL должно иметь переменное количество аргументов.Я хотел бы реализовать это поведение путем преобразования списка аргументов вызова TCL в std :: vector и передачи этого вектора в функцию C ++.Это будет более совместимо с существующим кодом проверки аргументов во многих функциях C ++.

Я попытался добавить следующее в мои файлы .h и .i, но это не работает, так как SWIG добавляет код для проверкичисло аргументов на стороне TCL.

//tclFunctions.h

static signed int some_function(const std::vector<std::string> args);
//baseFunc.i

%typemap(in) const std::vector<std::string> {
  Tcl_Obj **listobjv;
  int       nitems;
  int       i;
  if (Tcl_ListObjGetElements(interp, $input, &nitems, &listobjv) == TCL_ERROR){
     return TCL_ERROR;
  }

  for (i = 0; i < nitems; i++) {
     $1.push_back(Tcl_GetStringFromObj(listobjv[i],0));
  }
}

Это то, что проверяет аргументы в результирующем файле _wrap.c

 if(SWIG_GetArgs(interp,objc,objv,"o:test_function args ",(void *)0)==TCL_ERROR)
   SWIG_fail;

Как определить средство так, чтобывсякий раз, когда SWIG встречает std::vector<std::string> в качестве единственного аргумента функции, он принимает любое количество аргументов TCL и помещает их все в std::vector?Не является ли SWIG правильным инструментом для этого?Основное препятствие, которое у меня здесь есть, заключается в том, что SWIG обеспечивает подсчет аргументов, и большинство команд принимают произвольные аргументы в любом порядке.

Приложение не может попросить пользователя выполнить такие действия, как $some_function {arg1 arg2 arg3}, поскольку оно должно поддерживают команды, подобные этой.

#Only 2 args required but they can appear in any order.
report_timing -from [all_registers -clock_pins] \
  -to [all_registers -data_pins] -delay_type max \
  -path_type full_clock –nosplit \
  -max_paths 1 -nworst 1 \
  -trans -cap -net > tc_reg2reg_setup.rpt

1 Ответ

2 голосов
/ 16 февраля 2012

В данный момент я не перед компьютером, чтобы дать вам проверенный рабочий пример, но код, необходимый для перевода списков Tcl в вектор, выглядит примерно так:

%include <std_vector.i>
%include <std_string.i>
// instantiate template and give it a Pythonic name.
%template(vstr) std::vector<std::string>;

Тогда C ++ работает так:

int some_function(const std::vector<std::string> args);

Может вызываться в Tcl с помощью:

some_function {arg1 arg2 ... argN}

Редактировать

Извините, но я не до конца прочитал об ограничении. Переменные списки аргументов в действительности не поддерживаются SWIG, но вы можете написать прокси-функции в Tcl для функций SWIG:

proc report_timing {args} {
        swigs_report_timing $args
}

Это позволяет переменным аргументам, используемым report_timing, передаваться как единый список аргументов.

...