从 Tcl_HashTable 检索对象以销毁对象时出现问题
problem with retrieving object from Tcl_HashTable for destroy object
我正在尝试使用 Tcl C api 创建我的 C 元素的散列 table 并将它们 link 到某个字符串(键是字符串,值是指向的指针我的 C 对象)。
我的问题是,当我想为我的对象创建 destroy 函数时,这个 destroy 函数获取 clientData,它是可以转换为我的对象类型的指针,但我无法在散列 table 中找到这个对象指针(因为键是字符串)。
我该如何解决这个问题? Tcl_linkvar 在这种情况下有用吗?
我会提供一些我写的代码:
Tcl_InitHashTable(hash_table,TCL_STRING_KEYS);
...
int addMyObj(My_Obj * _obj , const char* _obj_name) {
Tcl_HashEntry * _new_entry;
int newptr;
if (_obj == NULL || strlen(_obj_name) == 0) return TCL_ERROR;
char * _name = (char *) malloc (strlen(_obj_name));
if (_name == NULL) return TCL_ERROR;
_new_entry=Tcl_CreateHashEntry(hash_table,_name,&newptr);
if (newptr == 0) {
printf("Error: obj with name %s already exists\n",_obj_name);
return TCL_ERROR;
}
Tcl_SetHashValue(_new_entry,_obj);
return TCL_OK;
}
void removeMyObj(const char * _obj_name) {
Tcl_HashEntry * _entry;
_entry = Tcl_FindHashEntry(hash_table,_obj_name);
// entry was found
if (_entry != NULL) {
My_Obj * _my_obj = (My_Obj * ) Tcl_GetHashValue(_entry);
Tcl_DeleteHashEntry(_entry);
delete _my_obj;
}
return;
}
My_Obj * getMyObj(const char * _obj_name) {
Tcl_HashEntry * _entry;
_entry = Tcl_FindHashEntry(hash_table,_obj_name);
// entry was found
if (_entry != NULL) {
My_Obj * _my_obj = (My_Obj * ) Tcl_GetHashValue(_entry);
return _my_obj;
}
return NULL;
}
// The problem is that in this function I should remove the object from hash table and delete it afterwards.
extern "C" void My_Obj_destroy(ClientData clientData) {
if (clientData != NULL) {
My_Obj * _my_obj = (My_Obj *) clientData;
removeMyObj(_my_obj); // should be removed from the hash table but it is receiving pointer to my_obj and not it's name
delete _my_obj ;
_my_obj = NULL;
}
return;
}
谢谢
有两种处理方法:
- 在对象中保留对象名称的副本。
- 保留一个指向
Tcl_HashEntry
的指针,该指针是在为散列 table 中的对象命名时创建的。 (它只是一个指针,但保证从创建到删除一直有效。)
在您的情况下,最好保留 Tcl_HashEntry *
— 它是 Tcl_CreateHashEntry()
返回的值或使用 Tcl_FindHashEntry()
查找的值 — 这样您就可以轻松删除。唯一棘手的一点是,这意味着您 必须 确保注意删除顺序,这意味着当您试图删除整个哈希 table.
我正在尝试使用 Tcl C api 创建我的 C 元素的散列 table 并将它们 link 到某个字符串(键是字符串,值是指向的指针我的 C 对象)。
我的问题是,当我想为我的对象创建 destroy 函数时,这个 destroy 函数获取 clientData,它是可以转换为我的对象类型的指针,但我无法在散列 table 中找到这个对象指针(因为键是字符串)。
我该如何解决这个问题? Tcl_linkvar 在这种情况下有用吗?
我会提供一些我写的代码:
Tcl_InitHashTable(hash_table,TCL_STRING_KEYS);
...
int addMyObj(My_Obj * _obj , const char* _obj_name) {
Tcl_HashEntry * _new_entry;
int newptr;
if (_obj == NULL || strlen(_obj_name) == 0) return TCL_ERROR;
char * _name = (char *) malloc (strlen(_obj_name));
if (_name == NULL) return TCL_ERROR;
_new_entry=Tcl_CreateHashEntry(hash_table,_name,&newptr);
if (newptr == 0) {
printf("Error: obj with name %s already exists\n",_obj_name);
return TCL_ERROR;
}
Tcl_SetHashValue(_new_entry,_obj);
return TCL_OK;
}
void removeMyObj(const char * _obj_name) {
Tcl_HashEntry * _entry;
_entry = Tcl_FindHashEntry(hash_table,_obj_name);
// entry was found
if (_entry != NULL) {
My_Obj * _my_obj = (My_Obj * ) Tcl_GetHashValue(_entry);
Tcl_DeleteHashEntry(_entry);
delete _my_obj;
}
return;
}
My_Obj * getMyObj(const char * _obj_name) {
Tcl_HashEntry * _entry;
_entry = Tcl_FindHashEntry(hash_table,_obj_name);
// entry was found
if (_entry != NULL) {
My_Obj * _my_obj = (My_Obj * ) Tcl_GetHashValue(_entry);
return _my_obj;
}
return NULL;
}
// The problem is that in this function I should remove the object from hash table and delete it afterwards.
extern "C" void My_Obj_destroy(ClientData clientData) {
if (clientData != NULL) {
My_Obj * _my_obj = (My_Obj *) clientData;
removeMyObj(_my_obj); // should be removed from the hash table but it is receiving pointer to my_obj and not it's name
delete _my_obj ;
_my_obj = NULL;
}
return;
}
谢谢
有两种处理方法:
- 在对象中保留对象名称的副本。
- 保留一个指向
Tcl_HashEntry
的指针,该指针是在为散列 table 中的对象命名时创建的。 (它只是一个指针,但保证从创建到删除一直有效。)
在您的情况下,最好保留 Tcl_HashEntry *
— 它是 Tcl_CreateHashEntry()
返回的值或使用 Tcl_FindHashEntry()
查找的值 — 这样您就可以轻松删除。唯一棘手的一点是,这意味着您 必须 确保注意删除顺序,这意味着当您试图删除整个哈希 table.