【问题标题】:Embedding Tcl in a C program在 C 程序中嵌入 Tcl
【发布时间】:2012-11-15 17:02:41
【问题描述】:

我正在尝试创建一个简单的 C++ 控制台应用程序,该应用程序在脚本上调用 nagelfar 语法检查器。我按照这里的说明进行操作:http://wiki.tcl.tk/19919,将tclstub85.lib 添加到我的输入中,将 tcl lib 目录添加到我的其他库中,并添加我的头目录。链接失败:

main.obj : error LNK2001: unresolved external symbol _tclStubsPtr 

这是我的链接命令行:

/OUT:"C:\Users\######\Documents\Visual Studio 2005\Projects\Nagelfar\Release\Nagelfar.exe"
/NOLOGO /LIBPATH:"C:\Tcl\lib" /MANIFEST 
/MANIFESTFILE:"Release\Nagelfar.exe.intermediate.manifest" /DEBUG
/PDB:"c:\users\######\documents\visual studio 2005\projects\nagelfar\release\Nagelfar.pdb"
/OPT:REF /OPT:ICF /LTCG /MACHINE:X86 /ERRORREPORT:PROMPT C:\Tcl\lib\tclstub85.lib
kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib
shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib 

这是完整的源代码,我可以使用 g++ 在 Linux 中编译和运行:

#include <stdlib.h>
#include <stdio.h>
#include <tcl.h>
#include <string.h>

Tcl_Interp * tcl_interp ;
char fileToCheck[] = "test.tcl";
char dbFile[] = "syntaxdb.tcl";

int main () {
    int code, argc;
    const char **argv;
    char command[1024];
    char *results = NULL; 
    tcl_interp = Tcl_CreateInterp();
    Tcl_SetVar2(tcl_interp, "::Nagelfar", "embedded", "1", 0);  
    code = Tcl_EvalFile(tcl_interp, "nagelfar.tcl"); 
    Tcl_LinkVar(tcl_interp, "::Nagelfar(chkResult)", (char *)&results, TCL_LINK_STRING); 
    sprintf(command, "synCheck %s %s", fileToCheck, dbFile); 
    code = Tcl_Eval(tcl_interp, command);
    printf("Raw Result: \r\n %s\r\n", results); 
    code = Tcl_SplitList(tcl_interp, results, &argc, &argv); 
    {
        int i;
        for (i = 0; i < argc; ++i)
        {
            printf("%d/%d: %s\r\n", i+1, argc, argv[i]); 
        }
    }
    Tcl_Free(results);
    return 0;
}

解决了我自己的问题:我有 x64 ActiveTcl,但正在链接一个 32 位项目。使用 x86 ActiveTcl 发行版解决了我的问题。

【问题讨论】:

  • 请添加您的解决方案作为您自己问题的答案。它可能对未来的访问者有所帮助。
  • 当然可以,但我不能再等几个小时 =D

标签: visual-studio linker visual-studio-2005 tcl unresolved-external


【解决方案1】:

您的错误消息告诉我们您需要一个存根表(一旦所有宏都展开后,Tcl 的名称为tclStubPtr),这反过来又表明定义了预处理器符号USE_TCL_STUBS。该符号用于编写为 Tcl 提供额外功能的库的情况。但是,如果您正在编写一个调用 Tcl 库中的函数的主应用程序 - 例如“运行此代码” - 您不能(轻松)使用存根机制,因为在 Tcl 之前需要存根表能够提供给您。

解决方法是定义USE_TCL_STUBS 并链接到主Tcl 库(可能是您系统上的C:\Tcl\lib\tcl85.dll)而不是tclstub85.lib。 (我对设置 Visual Studio 知之甚少,无法说出该配置的详细信息。)


您还应该将这一行添加到您的代码中调用Tcl_CreateInterp():

Tcl_FindExecutable(NULL);

该调用用于允许 Tcl 库核心进行自我初始化,做一些小事,比如让内存管理器和文件系统接口层工作。

【讨论】:

  • 谢谢,我确实发现我不应该使用存根,但问题的根源是我下载了一个 64 位 Tcl 库但有一个 32 位项目。
  • @user 哦,是的,那行不通。 (Stubs 是一项很棒的技术,但它并没有试图解决所有问题。这确实是一件好事,因为做好一件事总比做很多坏事要好。:-))
【解决方案2】:

解决了我自己的问题:我有 x64 ActiveTcl,但正在链接一个 32 位项目。使用 x86 ActiveTcl 发行版解决了我的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-22
    • 2013-04-24
    • 1970-01-01
    • 2010-09-09
    • 1970-01-01
    • 2013-04-10
    • 1970-01-01
    • 2015-09-30
    相关资源
    最近更新 更多