Hello ,
I have a list like this :
set myList {1 2 3 4 ::oo::Obj10 foo 10 bar}
A method like this :
method get {} {
# Gets object value.
return $_value
}
And my C code (C experts , Close your eyes!) :
// ...
for (int i = 0; i < count; ++i) {
if (Tcl_GetDoubleFromObj(interp, sub_elements[i], &d) == TCL_OK) {
// Do something...
} else if (!strncmp(Tcl_GetString(sub_elements[i]), "::oo::Obj", 9)) {
strcpy(obj, Tcl_GetString(sub_elements[i]));
strcat(obj, " get"); // method get
if (Tcl_Eval(interp, obj) != TCL_OK) {
return TCL_ERROR;
}
Tcl_ListObjAppendElement(interp, data, Tcl_GetObjResult(interp));
} else {
// Do something...
}
}
//...
I'm using 'strncmp' combined with Tcl_Eval.
I would like to know if there is other method to get the value of my
object in a list.
My code works but I don’t know if it is correct.
That's how you'd handle it, something like this ?
Create the list this way:
set myList [list 1 2 3 4 [::oo::Obj10 get] foo 10 bar]
You might be better off trying to avoid having to guess how to process the list objects.
However given that you are creating and executing a command from Tcl_Objs, consider using Tcl_EvalObjv, and instead of checking that the string value looks like an object name just execute the get method on the Tcl_Obj and check if there was an error.
// set up command object array (consider doing this only once in your application)
// I think this is the correct way to initalize a C array to NULLs ?? Tcl_Obj* cmd[3] = {NULL, NULL, NULL};
// second word of command is "get"
cmd[1] = Tcl_NewStringObj("get", -1);
// make sure the "get" does not disappear at an inopportune time. Tcl_IncrRefCount(cmd[1]);
// need to decrement the reference count (Tcl_DecrRefCount(cmd[1]);)
// just before the cmd[] array goes out of scope to avoid a memory leak
...
// try executing a get method on the current list entry
// if there is a chance the sub element has a zero reference count (unlikely for a list element),
// increment it here (and remember to decrement it later to avoid a memory leak)
cmd[0] = sub_elements[i];
if (TCL_OK == Tcl_EvalObjv(interp, cmd, 0)) {
DO SOMETHING with the result in interp
} else {
TRY SOMETHING ELSE
}
I did not compile or execute this YMMV
Le lundi 5 juin 2023 à 17:05:22 UTC+2, clt.to...@dfgh.net a écrit :
Create the list this way:
set myList [list 1 2 3 4 [::oo::Obj10 get] foo 10 bar]
I can't, the goal here is to check each type, so I need to keep the
name of the object.
Nicolas Robert <nicolasro...@gmail.com> wrote:
Le lundi 5 juin 2023 à 17:05:22 UTC+2, clt.to...@dfgh.net a écrit :
Create the list this way:
set myList [list 1 2 3 4 [::oo::Obj10 get] foo 10 bar]
I can't, the goal here is to check each type, so I need to keep theThen consider changing your list definition:
name of the object.
set myList [list val 1 val 2 val 3 val 4 obj ::oo::Obj10 val foo val 10 val bar]
Then (in Tcl) you could process something like this way:
foreach {type content} $myList {
switch -exact -- $type {
val { # do something with a value }
obj { # do a [$content get] to get the value, then do something
with the value and the object name }
}
}
A similar 'loop' in C could be crafted but I'm not going to attempt to
type that out here (it would likely contain many syntax errors).
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 493 |
Nodes: | 16 (2 / 14) |
Uptime: | 192:37:24 |
Calls: | 9,707 |
Calls today: | 2 |
Files: | 13,740 |
Messages: | 6,180,161 |