如何链接到Tcl C API中的tclOO函数

时间:2018-01-20 22:47:17

标签: c tcl linker-errors

作为我不能做的一个简短例子:

#include <tcl.h>
#include <tclOO.h>

int main(void) {
    Tcl_Interp *interp = Tcl_CreateInterp();
    Tcl_Obj *obj = Tcl_NewStringObj("myObject", -1);
    Tcl_Object object = Tcl_GetObjectFromObj(interp, obj);
    return 0;
}

然后编译:

gcc main.c -o tclOOTest -ltcl

我当然从链接器中收到错误,因为我没有链接到具有Tcl_GetObjectFromObj定义的库。麻烦的是我不知道链接哪个库。我认为自从8.6以来tclOO已经内置到tcl中(这就是我正在使用的)。

这是错误:

/tmp/ccZnpdY8.o: In function `main':
main.c:(.text+0x33): undefined reference to `Tcl_GetObjectFromObj'
collect2: error: ld returned 1 exit status

1 个答案:

答案 0 :(得分:2)

与Tcl的其余部分不同,TclOO API仅通过存根表导出自身。在#define Tcl头文件之前,您应该USE_TCL_STUBS符号#include为1,并链接到tclstub库。 (无论如何,这是构建扩展的推荐方法。)

[编辑]:如果您在程序中嵌入Tcl,则需要more complex procedure。基本上,您需要将程序划分为应用程序部分和内部扩展部分。调用Tcl_CreateInterp的部分很可能是应用程序部分,访问TclOO API的部分是扩展(并且需要在初始化函数中调用Tcl_InitStubsTcl_OOInitStubs)。

扩展部分需要使用USE_TCL_STUBS定义进行编译。 (因为它很重要,你可以将它作为#define放在文件的顶部。维基页面也提到了USE_TCLOO_STUBS,但USE_TCL_STUBS隐含了这一点。 )扩展部件需要在没有它的情况下构建。在开始运行任何(非内置)脚本之前,您可以在Tcl_CreateInterp调用之后立即调用初始化函数来安装内部扩展。然后,当您链接两者libtclstublibtcl相关联的所有内容时。

这种复杂性的原因是TclOO本身就是一个单独的扩展,并且从不支持外部API引用。我可能应该放宽对Tcl 8.7的限制......