TCL-C API:Tcl_LinkVar功能使用 [英] TCL-C API: Tcl_LinkVar function use
问题描述
我想一个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屋!