TCL-C API:Tcl_LinkVar功能使用 [英] TCL-C API: Tcl_LinkVar function use

查看:350
本文介绍了TCL-C API:Tcl_LinkVar功能使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想一个Tcl变量,才能链接到一个C变量间传递C线程的创建过程中的指针最新,并有TCL-C线程共享变量(我不认为我可以使用本机TCL线程共享变量函数)。
我有一些困难,这两个变量联系起来。
这里就是我要做的:

I am trying to link a Tcl variable to a C variable in order to pass the pointer to the latest during C thread creation and have a TCL-C thread shared variable (I don't think I can use native TCL Thread Shared Variable functions). I have some difficulties to link both variables. Here is how I do:

#Tcl code, calling the C function:
set linkedVar 98
puts "linkedVar: $linkedVar"
load [file join [pwd] libCextension[info sharedlibextension]]
set threadId [createThreadC]
puts "Created thread n° $threadId"
puts "linkedVar: $linkedVar"

createThreadC 函数创建一个C线程,返回其ID,并试图创建 linkedVar 。<链接/ p>通过Tcl的名为

The createThreadC function creates a C thread, return its ID and tries to create a link with linkedVar.

// C function called by Tcl
static int
createThreadC_Cmd(
    ClientData cdata,
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    int linkedVar=2;
    Tcl_LinkVar(interp, "linkedVar", (char *) &linkedVar, TCL_LINK_INT);
    linkedVar=1;
    ...
    # Thread creation, return Tcl object with thread ID
    ...
    return TCL_OK;  
}

下面是输出:

linkedVar: 98
Created thread n° -1227199680
linkedVar: 35

linkedVar 值不同,作为C程序必须的,但它存储了错误的变量,应该是1,而不是35个。
难道是(字符*)及?linkedVar 投这是不对的。

The linkedVar value changed, as C program had to, but it stores the wrong variable, should be 1 instead of 35. Is it the (char *) &linkedVar cast which is wrong?

推荐答案

我会说同样的东西,多纳尔,而且还写了演示。所以这里是 - 基本上是你的链接可变生命应该跨preTER寿命匹配

I was going to say the same stuff as Donal, but also wrote a demo. So here it is - basically your linked variable lifetime should match the interpreter lifetime.

#include <tcl.h>

typedef struct Shared {
    Tcl_Interp *interp;
    int id;
} Shared;

static int
UpdateCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Shared *sharedPtr = (Shared *)clientData;
    if (objc != 1) {
        Tcl_WrongNumArgs(interp, 1, objv, "");
        return TCL_ERROR;
    }
    ++sharedPtr->id;
    return TCL_OK;
}
static void
DeleteProc(ClientData clientData)
{
    Shared *sharedPtr = (Shared *)clientData;
    Tcl_UnlinkVar(sharedPtr->interp, "shared_id");
    Tcl_Release(sharedPtr->interp);
    Tcl_Free(clientData);
}

int DLLEXPORT
Testlink_Init(Tcl_Interp *interp)
{
    Shared *sharedPtr;
    if (Tcl_InitStubs(interp, "8.4", 0) == NULL) {
        return TCL_ERROR;
    }
    sharedPtr = (Shared *)Tcl_Alloc(sizeof(Shared));
    sharedPtr->interp = interp;
    sharedPtr->id = 0;
    Tcl_Preserve(sharedPtr->interp);
    Tcl_LinkVar(interp, "shared_id", (char *)&sharedPtr->id, TCL_LINK_INT);
    Tcl_CreateObjCommand(interp, "update_shared", UpdateCmd, sharedPtr, DeleteProc);
    Tcl_PkgProvide(interp, "testlink", "1.0");
    return TCL_OK;
}

使用(建筑物使用过MSVC 6):

Usage (building too using msvc 6):

C:\src>cl -nologo -Od -MD -I\opt\tcl\include -DUSE_TCL_STUBS -c tcl_link.c
tcl_link.c

C:\src>link -dll -debug -out:tcl_link.dll tcl_link.obj \opt\tcl\lib\tclstub85.lib
Microsoft (R) Incremental Linker Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

C:\src>tclsh
% load tcl_link.dll testlink
% set shared_id
0
% update_shared
% set shared_id
1

这说明通过利用命令清理功能清理东西的一种方式。

This shows one way to clean things up by leveraging the command cleanup function.

如果你使用多线程,也有各地的Tcl间preters你必须非常小心。一个Tcl插值绑定到其创建的线程。所以如果你想ç线程之间传递共享结构,先松插值成员。在这种情况下,我有这种结构的寿命由应用程序处理。只要您共享结构具有寿命长于有一个命令而这是clientData那么一切都会好的,你不跨preTER中需要清理的跨preTER。

You must be very careful if you use multiple threads and also have Tcl interpreters around. A Tcl interp is tied to the thread it was created on. So if you want the Shared structure to be passed among C threads you should loose the interp member. In that case I'd have this structure lifetime being handled by the application. Provided your Shared structure has a lifetime that is longer than any interpreter that has a command for which this is the clientData then everything will be ok and you don't need to cleanup within the interpreter.

这篇关于TCL-C API:Tcl_LinkVar功能使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆