如何使用 SWIG 创建带有可选参数的 TCL 函数?

发布于 2024-12-01 14:12:41 字数 805 浏览 1 评论 0原文

我有一个简单的 c/c++ 应用程序,它有一个可选的 TCL 解释器以及使用 SWIG 生成的函数包装器。对于某些函数,所有参数都是可选的。这通常是如何处理的?我想支持这样的 TCL 命令,其中任何参数都是可选的,但 C 函数采用固定参数:

 //TCL command
 get_list [options] filename
   -opt1
   -opt2
   -opt3 arg1 
   -opt4 arg2
   filename

//C function
static signed get_list(bool         opt1,
                       bool         opt2,
                       char       * arg1,
                       objectType * arg2,
                       char       * fileName)

目前我有这样的东西:

static pList * get_list(char    * arg1=NULL,
                        char    * arg2=NULL, 
                        char    * arg3=NULL,  
                        tObject * arg4=NULL)

这有很多问题,例如强制对象指针始终是最后一个参数。 SWIG 文档详细讨论了带有变量参数的 C 函数,使用“...”,但我认为这不是我需要的。我希望修复 C 函数参数。

I have a simple c/c++ app that has an optional TCL interpreter with the function wrappers generated using SWIG. For several of the functions all the arguments are optional. How is this typically handled? I'd like to support a TCL command like this, where any of the arguments are optional but the C function takes fixed arguments:

 //TCL command
 get_list [options] filename
   -opt1
   -opt2
   -opt3 arg1 
   -opt4 arg2
   filename

//C function
static signed get_list(bool         opt1,
                       bool         opt2,
                       char       * arg1,
                       objectType * arg2,
                       char       * fileName)

Currently I have something like this:

static pList * get_list(char    * arg1=NULL,
                        char    * arg2=NULL, 
                        char    * arg3=NULL,  
                        tObject * arg4=NULL)

This has many problems such as enforcing the object pointer is always the last argument. The SWIG documentation talks at length about C functions with variable arguments using "..." but I don't think this is what I need. I'd like the C function arguments to be fixed.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

葬花如无物 2024-12-08 14:12:41

最简单的方法是在外部包装一个 Tcl 过程,如下所示:

rename get_list original.get_list
proc get_list args {
    if {[llength $args] == 0 || [llength $args] % 2 == 0} {
        error "wrong # args: ...";   # Do a proper error message here!
    }
    # Handle the required argument
    set filename [lindex $args end]
    # Initialize the defaults
    array set opts {
        -opt1 false
        -opt2 false
        -opt3 ""
        -opt4 ""
    }
    # Merge in the supplied options
    foreach {opt val} [lrange $args 0 end-1] {
        if {![info exist opts($opt)]} {
            error "unrecognized option \"$opt\""
        }
        set opts($opt) $value
    }
    # Hand off to C level...
    original.get_list $opts(-opt1) $opts(-opt2) $opts(-opt3) $opts(-opt4) $filename
}

如果您有 Tcl 8.6,则最后的切换最好使用 tailcall 完成,以便从 Tcl 堆栈中删除重写代码。但这并不重要,因为 SWIGged 代码很少解析 Tcl 命令和变量的名称。

The easiest method is to wrap a Tcl procedure around the outside, like this:

rename get_list original.get_list
proc get_list args {
    if {[llength $args] == 0 || [llength $args] % 2 == 0} {
        error "wrong # args: ...";   # Do a proper error message here!
    }
    # Handle the required argument
    set filename [lindex $args end]
    # Initialize the defaults
    array set opts {
        -opt1 false
        -opt2 false
        -opt3 ""
        -opt4 ""
    }
    # Merge in the supplied options
    foreach {opt val} [lrange $args 0 end-1] {
        if {![info exist opts($opt)]} {
            error "unrecognized option \"$opt\""
        }
        set opts($opt) $value
    }
    # Hand off to C level...
    original.get_list $opts(-opt1) $opts(-opt2) $opts(-opt3) $opts(-opt4) $filename
}

If you've got Tcl 8.6, that last handoff is best done with tailcall so the rewriting code is cut out of the Tcl stack. It's not vital though, as SWIGged code rarely resolves names of Tcl commands and variables.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文