SWIG生成了具有任意数量参数的TCL包装器

时间:2012-02-15 23:38:07

标签: c++ tcl swig

我正在使用SWIG生成用于从TCL调用C ++函数的包装代码。我的.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 个答案:

答案 0 :(得分:2)

我现在不在电脑前为您提供经过验证的工作示例,但将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使用的变量参数作为单个参数列表传递。