我正在使用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
答案 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
使用的变量参数作为单个参数列表传递。