tcl

编程入门 行业动态 更新时间:2024-10-26 06:32:42
tcl_findLibrary不起作用(tcl_findLibrary doesn't work)

我正在尝试运行新编译的程序,用Tcl和Tk编写。 运行时我收到一个错误:

felix@Astroserver:~/Документы/Simon$ sudo ./simon1
invalid command name "tcl_findLibrary"
 

我正在运行Ubuntu 11.04,我已经安装了Tcl和Tk(因为我能够成功构建程序)。

如果我正在运行愿望

% tcl_findLibrary
wrong # args: should be "tcl_findLibrary basename version patch initScript enVarName varName"
 

有人可以帮忙吗?

main(int argc, char *argv[])
{
    Tcl_Interp *interp;
    int main_window;

    char *args;
    char buf[20];   /* intermediate storage to pass a value to TCL */
    char *tcl_command;  /* points to a string of a TCL command line */
    int tcl_return_value;/* is either TCL_OK or TCL_ERROR */

    interp = Tcl_CreateInterp();

    /* Command line arguments are passed to TCL. TCL stores in argv0 the name
    of the command, that is argv[0], in argv all other arguments, and in
    argc the number of arguments. */

    args = Tcl_Merge(argc - 1, argv+1);
    Tcl_SetVar(interp, "argv", args, TCL_GLOBAL_ONLY);
    ckfree(args); /* Tcl_Merge allocates memory for the returned string */

    sprintf(buf, "%d", argc - 1);
    Tcl_SetVar(interp, "argc", buf, TCL_GLOBAL_ONLY);

    Tcl_SetVar(interp, "argv0", argv[0], TCL_GLOBAL_ONLY);

    /* Create main window and do some initialization for Tcl/Tk */
    main_window = Tk_Init(interp);
    if (main_window != TCL_OK) {
        fprintf(stderr, "%s\n", interp->result);
        exit(1);
    }

    if (Tcl_AppInit(interp) == TCL_ERROR) {
        printf("%s\n",interp->result);
        exit(1);
    }


    /* testing if environment variable SIMON_PATH is specified */
    tcl_return_value = Tcl_Eval(interp, 
            "if {![info exist env(SIMON_PATH)]} {"
            "puts \"Environment variable SIMON_PATH is missing!\";"
            "exit }");

    /* Evaluate my GUI simon.tk */

    /* the 33 is the lenght of the string "source $env(SIMON_PATH)/simon.tk" */
    tcl_command = (char *)MyMalloc(33 * sizeof(char));
    strcpy(tcl_command,"source $env(SIMON_PATH)/simon.tk");

    tcl_return_value = Tcl_Eval(interp, tcl_command);
    if (*interp->result != 0) printf("%s \n", interp->result);
    if (tcl_return_value != TCL_OK)
    {
        printf("simon.tk at line: %d\n",interp->errorLine);
        exit(1);
    }

    /* Waiting for interactive events. */

    Tk_MainLoop();
}

int Tcl_AppInit(Tcl_Interp *interp)
{  
    if (Tcl_Init(interp) == TCL_ERROR) {
        return TCL_ERROR;
}
    if (Tk_Init(interp) == TCL_ERROR) {
        return TCL_ERROR;
}
    Tcl_CreateCommand(interp, "set_parser", SET_Parser, (ClientData) NULL,
        (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "set_c2tcl_data", SET_C2TclData,
        (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);

    Tcl_CreateCommand(interp, "set_free_and_reset_module_data", 
        SET_FreeAndResetModuleData,
        (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "set_free_and_reset_global_data", 
        SET_FreeAndResetGlobalData,
        (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "set_reset_sim_control_parameter", 
        SET_ResetSimControlParameter,
        (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "set_random_number", SET_RandomNumber,
        (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "set_scale_graph_data", SET_ScaleGraphData,
        (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);

    return TCL_OK;
}

I'm trying to run freshly compiled program, written with Tcl&Tk. When running it I get an error:

felix@Astroserver:~/Документы/Simon$ sudo ./simon1
invalid command name "tcl_findLibrary"
 

I'm running Ubuntu 11.04, I have installed Tcl&Tk (cause I was able to succesfully build the program).

If I'm running wish:

% tcl_findLibrary
wrong # args: should be "tcl_findLibrary basename version patch initScript enVarName varName"
 

Could anyone help?

main(int argc, char *argv[])
{
    Tcl_Interp *interp;
    int main_window;

    char *args;
    char buf[20];   /* intermediate storage to pass a value to TCL */
    char *tcl_command;  /* points to a string of a TCL command line */
    int tcl_return_value;/* is either TCL_OK or TCL_ERROR */

    interp = Tcl_CreateInterp();

    /* Command line arguments are passed to TCL. TCL stores in argv0 the name
    of the command, that is argv[0], in argv all other arguments, and in
    argc the number of arguments. */

    args = Tcl_Merge(argc - 1, argv+1);
    Tcl_SetVar(interp, "argv", args, TCL_GLOBAL_ONLY);
    ckfree(args); /* Tcl_Merge allocates memory for the returned string */

    sprintf(buf, "%d", argc - 1);
    Tcl_SetVar(interp, "argc", buf, TCL_GLOBAL_ONLY);

    Tcl_SetVar(interp, "argv0", argv[0], TCL_GLOBAL_ONLY);

    /* Create main window and do some initialization for Tcl/Tk */
    main_window = Tk_Init(interp);
    if (main_window != TCL_OK) {
        fprintf(stderr, "%s\n", interp->result);
        exit(1);
    }

    if (Tcl_AppInit(interp) == TCL_ERROR) {
        printf("%s\n",interp->result);
        exit(1);
    }


    /* testing if environment variable SIMON_PATH is specified */
    tcl_return_value = Tcl_Eval(interp, 
            "if {![info exist env(SIMON_PATH)]} {"
            "puts \"Environment variable SIMON_PATH is missing!\";"
            "exit }");

    /* Evaluate my GUI simon.tk */

    /* the 33 is the lenght of the string "source $env(SIMON_PATH)/simon.tk" */
    tcl_command = (char *)MyMalloc(33 * sizeof(char));
    strcpy(tcl_command,"source $env(SIMON_PATH)/simon.tk");

    tcl_return_value = Tcl_Eval(interp, tcl_command);
    if (*interp->result != 0) printf("%s \n", interp->result);
    if (tcl_return_value != TCL_OK)
    {
        printf("simon.tk at line: %d\n",interp->errorLine);
        exit(1);
    }

    /* Waiting for interactive events. */

    Tk_MainLoop();
}

int Tcl_AppInit(Tcl_Interp *interp)
{  
    if (Tcl_Init(interp) == TCL_ERROR) {
        return TCL_ERROR;
}
    if (Tk_Init(interp) == TCL_ERROR) {
        return TCL_ERROR;
}
    Tcl_CreateCommand(interp, "set_parser", SET_Parser, (ClientData) NULL,
        (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "set_c2tcl_data", SET_C2TclData,
        (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);

    Tcl_CreateCommand(interp, "set_free_and_reset_module_data", 
        SET_FreeAndResetModuleData,
        (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "set_free_and_reset_global_data", 
        SET_FreeAndResetGlobalData,
        (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "set_reset_sim_control_parameter", 
        SET_ResetSimControlParameter,
        (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "set_random_number", SET_RandomNumber,
        (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "set_scale_graph_data", SET_ScaleGraphData,
        (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);

    return TCL_OK;
}

                

最满意答案

你正在调用Tcl_CreateInterp而不是Tcl_Main ,这是好的,但要求你先调用Tcl_FindExecutable (初始化库)。 第一次调用Tcl的C接口必须始终是Tcl_FindExecutable或Tcl_Main (因为它为您调用Tcl_FindExecutable )。 当Tcl没有初始化时,各种奇怪的东西都可能出错; 在这种情况下,我们不保证代码的正确操作。

看过代码后,我建议切换到使用Tk_Main (如Tcl_Main ,但启用Tk)。 你最终会得到这样的代码:

static int AppInit(Tcl_Interp *interp) {
    /* Basic init */
    if (Tcl_Init(interp) == TCL_ERROR)
        return TCL_ERROR;
    if (Tk_Init(interp) == TCL_ERROR)
        return TCL_ERROR;
    Tcl_StaticPackage(interp, "Tk", Tk_Init, Tk_SafeInit);
    /* Make your commands here */
    Tcl_CreateCommand(interp, "set_parser",           SET_Parser, NULL, NULL);
    Tcl_CreateCommand(interp, "set_c2tcl_data",       SET_C2TclData, NULL, NULL);
    Tcl_CreateCommand(interp, "set_random_number",    SET_RandomNumber, NULL, NULL);
    Tcl_CreateCommand(interp, "set_scale_graph_data", SET_ScaleGraphData, NULL, NULL);
    Tcl_CreateCommand(interp, "set_free_and_reset_module_data", 
            SET_FreeAndResetModuleData, NULL, NULL);
    Tcl_CreateCommand(interp, "set_free_and_reset_global_data", 
            SET_FreeAndResetGlobalData, NULL, NULL);
    Tcl_CreateCommand(interp, "set_reset_sim_control_parameter", 
            SET_ResetSimControlParameter, NULL, NULL);
    /* Can't remember if you need this */
    Tcl_SetVar(interp, "tcl_rcFileName", "~/.simonrc", TCL_GLOBAL_ONLY);
    /* Now your remaining initialization - assume no error for this! */
    Tcl_Eval(interp, 
            "if {![info exist env(SIMON_PATH)]} {"
            "puts \"Environment variable SIMON_PATH is missing!\";"
            "exit }");
    /* Read your startup code */
    return Tcl_Eval(interp, "source $env(SIMON_PATH)/simon.tk");
}
int main(int argc, char **argv) {
    Tk_Main(argc, argv, AppInit);
    return 0; /* Not Reached */
}

You're calling Tcl_CreateInterp instead of Tcl_Main, which is OK but requires that you call Tcl_FindExecutable first (to initialize the library). The first call into Tcl's C interface must always be either Tcl_FindExecutable or Tcl_Main (because that calls Tcl_FindExecutable for you). When Tcl isn't initialized, all sorts of odd things can go wrong; we don't warrant the correct operation of the code in that case.

Having seen your code, I'd recommend switching to using Tk_Main (like Tcl_Main, but Tk-enabled). You'd end up with code like this:

static int AppInit(Tcl_Interp *interp) {
    /* Basic init */
    if (Tcl_Init(interp) == TCL_ERROR)
        return TCL_ERROR;
    if (Tk_Init(interp) == TCL_ERROR)
        return TCL_ERROR;
    Tcl_StaticPackage(interp, "Tk", Tk_Init, Tk_SafeInit);
    /* Make your commands here */
    Tcl_CreateCommand(interp, "set_parser",           SET_Parser, NULL, NULL);
    Tcl_CreateCommand(interp, "set_c2tcl_data",       SET_C2TclData, NULL, NULL);
    Tcl_CreateCommand(interp, "set_random_number",    SET_RandomNumber, NULL, NULL);
    Tcl_CreateCommand(interp, "set_scale_graph_data", SET_ScaleGraphData, NULL, NULL);
    Tcl_CreateCommand(interp, "set_free_and_reset_module_data", 
            SET_FreeAndResetModuleData, NULL, NULL);
    Tcl_CreateCommand(interp, "set_free_and_reset_global_data", 
            SET_FreeAndResetGlobalData, NULL, NULL);
    Tcl_CreateCommand(interp, "set_reset_sim_control_parameter", 
            SET_ResetSimControlParameter, NULL, NULL);
    /* Can't remember if you need this */
    Tcl_SetVar(interp, "tcl_rcFileName", "~/.simonrc", TCL_GLOBAL_ONLY);
    /* Now your remaining initialization - assume no error for this! */
    Tcl_Eval(interp, 
            "if {![info exist env(SIMON_PATH)]} {"
            "puts \"Environment variable SIMON_PATH is missing!\";"
            "exit }");
    /* Read your startup code */
    return Tcl_Eval(interp, "source $env(SIMON_PATH)/simon.tk");
}
int main(int argc, char **argv) {
    Tk_Main(argc, argv, AppInit);
    return 0; /* Not Reached */
}

                    
                     
          

更多推荐

本文发布于:2023-07-05 14:31:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1038455.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:tcl

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!