关于我的question我现在尝试在另一个函数中获取这个值。
到目前为止,我主要使用Tcl_Obj
来检索:
- char
- 双
- 列表值
- 等等
但不是指针地址。根据Tcl API,这样的函数不存在(我认为.)。
网上没有太多的例子(最重要的是,我不知道在哪里/找什么),我想这个页面(Tcl Handles)可能会有帮助,但我不确定。
谁能给我给予一下?
编辑(在@n的评论之后。可能是AI):
critcl::cproc initContext {Tcl_Interp* interp} ok {
Context ctx;
Init(&ctx);
// printf("pointer %p\n", &ctx);
char hexstr[24];
sprintf(hexstr,"%p", (void*)&ctx);
Tcl_SetObjResult(interp, Tcl_NewStringObj(hexstr, -1));
return TCL_OK;
}
critcl::cproc useContext {Tcl_Interp* interp Tcl_Obj* ctxObj} ok {
int len;
char *strPointer;
// Gets context pointer as a string
strPointer = Tcl_GetStringFromObj(ctxObj, &len);
// @Donal Fellows comment :
// "convert a pointer to an integer
// (cast to intptr_t first) and an integer to a pointer"
// I would like to reuse this context in this C function like this
// showContext(&ctx);
return TCL_OK;
}
# Tcl code
set ctx [initContext] ; # Gets context...
useContext $ctx ; # Using context
编辑2(在@n的评论之后。可能是AI。一个最小可重复的例子):
我的C代码可以用:
void testContext() {
Context ctx;
if (Init(&ctx) != SUCCESS)
return;
showContext(&ctx);
}
注:* 我不知道这是否重要,我使用critcl(我认为哲学是一样的,我希望如此!)*.
2条答案
按热度按时间fbcarpbf1#
你可以将一个指针转换成一个整数(先转换成
intptr_t
),然后将一个整数转换成指针,这样就可以了。但它非常不安全;没有好的办法直接验证这些东西!但有些事你可以做。最低级别的验证是用名称来假装指针编号(可能是从它所指向的事物的名称派生出来的?)这样你就不会不小心把它们完全弄混了;你可以在解析值的时候很容易地检查它。许多Tcl扩展都是这样做的。
更高级别的验证是在Tcl解释器中存储一个哈希表(作为命令的客户端数据或通过
Tcl_SetAssocData
),并使用它来检查来自脚本的值是否是给它的值,并且还没有被无效(当你释放它指向的东西时,你通常会无效)。像这样指针可以通过脚本,但只能作为不透明值。(我在那个wiki页面上的旧代码正在做一种更高级的形式,将Map缓存在句柄标记本身中。)Tcl在Windows上为它的原生通道句柄做了一些非常类似的事情(其他平台使用FD代替)。(If你有这样一个表,它使列出当前已知的值成为一种简单的内省起点。)
对此的一个轻微扩展是使用计数器(或者RNG,如果您喜欢)来生成这些句柄名称的变化部分,而不是指针部分本身。就像你不使用安全检查就不可能返回Map...但通常没这个必要这就是合成通道(请参见
chan create
)创建其句柄的方式。(TclOO * 似乎 * 这样做,但做了其他事情;里面有更多的活动部件)。在这方面需要注意的主要事情是,当您删除它指向的值(或以其他方式使其不可用)时,您需要停止Map的工作。Tcl不提供垃圾收集的帮助(你可以在某种程度上欺骗它,相当多的代码是这样做的,但它在形式上是脆弱的,不受支持)。明确删除是官方首选的方法。
pvabu6sv2#
你不需要“指针的地址”。你只需要一个指针值。
打印一个指向一个字符串的指针,其大小为
sprintf(buffer, "%p", pointer)
,然后将其转换为Tcl对象。逆操作将是
sscanf(buffer, "%p", &pointer)
从Tcl对象获取一个字符串并读取它:下面是一个完整的测试工作的Tcl扩展,使用上述方法。请注意上下文是静态的,而不是任何命令的本地上下文。您可能需要动态地分配它,并使用Tcl对象生存期管理来管理它的生存期,但这超出了本答案的范围。