I've ventured on creating a Tcl command trough a C routine. I've followed the manual guidelines. My C routine checks the validity of a selected option for the currently displayed histogram. Therefore it returns a Boolean value that, according to the C <-> Tcl communucation protocol, I have encoded as TCL_ERROR (= FALSE) and TCL_OK (TRUE). WHenthis command is called in a Tcl proc, the interpreter is supposed to perform two different actions according to the returned Boolean value. How can I fetch this returned Boolean result (TCL_ERROR/ TCL_OK) from the Tcl proc that executes the C-created command ? What if I wrote 1 (FALSE) or 0 (TRUE) in a string and have the C routine return this 1-character string ? Would it be easier to get the result of the teest from the caling TCL proc ? Please, find in the following the code that implements (according to my best resolution) the C-created command and the callind Tcl proc. Thank you, Maura ************************************************************************************************************* * C routine * ************************************************************************************************************* static int check_hist_aint_option_cb( ClientData clientData, Tcl_Interp *interp, int argc, char *argv[] ) { int i; if ( hg.active_ <= 0 ){ Tcl_SetResult( interp, "Histogram not active !", TCL_STATIC ); return TCL_ERROR; } i = -1 while ((++i < Length_of_AINT_histo_ID) && (hg.hid_ != AINT_histo_ID[i])) ; if (i >= Length_of_AINT_histo_ID) { Tcl_SetResult( interp, "Renormalization option unavailable for the current histogram !", TCL_STATIC ); return TCL_ERROR; } return TCL_OK; } ************************************************************************************************************* * Tcl calling proc * ************************************************************************************************************* proc change_RZ_hist_aint {} { global aint if (check_hist_aint_option) { puts "\n current AINT value: $aint" delete_hist_bar; draw_hist_bar; } else tk_messageBox -default ok -type ok -icon error -message "AINT does not apply to the current histogram" }
When writing Tcl commands in C, you need to make a distinction between the "status code" and the return value. Ironically, you provide the status code with the [return] command, and you provide the return value with Tcl_SetObjResult, Tcl_AppendResult, or some other such command. I can see where you're going with your code; if you want to go that route, you should do something like this: if {[catch {check_hist_aint_option}]} { # deal with the error } else { # proceed as normal } Another alternative is to return TCL_OK as the status code in either case, and return true or false as the result. Something like: if (can_do_histogram) { Tcl_SetObjResult(interp, Tcl_NewBooleanObj(1)); } else { Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0)); } return TCL_OK; Your Tcl code can then go like this: if {[check_hist_aint_option]} { # proceed with histogram } else { # give negative feedback } Does that help?
Sure. It does help. I will try the first alternative. I haven't quite digested the use of Tcl "objects" as a communication tool with C. Thank you so much, Maura
Dnia 24 May 2006 21:29:19 -0700, maura.monville@gmail.com skrobie: > I've ventured on creating a Tcl command trough a C routine. I've > followed the manual guidelines. > My C routine checks the validity of a selected option for the currently > displayed histogram. > Therefore it returns a Boolean value that, according to the C <-> Tcl > communucation protocol, I have encoded as TCL_ERROR (= FALSE) and > TCL_OK (TRUE). > WHenthis command is called in a Tcl proc, the interpreter is supposed > to perform two different actions according to the returned Boolean > value. > How can I fetch this returned Boolean result (TCL_ERROR/ TCL_OK) from > the Tcl proc that executes the C-created command ? > What if I wrote 1 (FALSE) or 0 (TRUE) in a string and have the C > routine return this 1-character string ? Would it be easier to get the > result of the teest from the caling TCL > proc ? The Tcl_SetResult sets the value that is returned by the command from the Tcl side. And the returned value by the C function that implements the command sets the command's "status code", that is, it is something like "exceptions" in other languages. The interpretation of this code depends on what is calling it. If the returned value is TCL_OK, nothing happens. If the returned value is TCL_ERROR then the "error" (or "1") status code is returned, which causes abnormal execution termination. This can be next caught by the [catch] command, which will set the result to the given variable name and return the status code (in numerical convention, that is, 1 for TCL_ERROR). You seemed also to use the [if] command incorrectly, so this is how you could implement it: if { [catch {check_hist_aint_option} result] != 0 } { puts "\n current AINT value: $aint" delete_hist_bar draw_hist_bar } else { tk_messageBox ... -message "AINT does not apply to the current histogram: $result" } -- // _ ___ Michal "Sektor" Malecki <sektor(whirl)kis.p.lodz.pl> \\ L_ |/ `| /^\ ,() <ethourhs(O)gmail.com> // \_ |\ \/ \_/ /\ C++ bez cholesterolu: http://www.intercon.pl/~sektor/cbx "I am allergic to Java because programming in Java reminds me casting spells"
In article <1148531359.044694.114430@j33g2000cwa.googlegroups.com>, maura.monville@gmail.com <maura.monville@gmail.com> wrote: >I've ventured on creating a Tcl command trough a C routine. I've >followed the manual guidelines. . . . >static int >check_hist_aint_option_cb( ClientData clientData, > Tcl_Interp *interp, > int argc, char *argv[] ) { > int i; > > if ( hg.active_ <= 0 ){ > Tcl_SetResult( interp, > "Histogram not active !", > TCL_STATIC ); > return TCL_ERROR; > } > > i = -1 > while ((++i < Length_of_AINT_histo_ID) && (hg.hid_ != >AINT_histo_ID[i])) ; > if (i >= Length_of_AINT_histo_ID) { > Tcl_SetResult( interp, > "Renormalization option unavailable for the current >histogram !", > TCL_STATIC ); > return TCL_ERROR; > } > return TCL_OK; >} > > >************************************************************************************************************* >* Tcl calling proc > * >************************************************************************************************************* > >proc change_RZ_hist_aint {} { > > global aint > > > if (check_hist_aint_option) { > puts "\n current AINT value: $aint" > delete_hist_bar; > draw_hist_bar; > } > else > tk_messageBox -default ok -type ok -icon error -message "AINT >does not apply to the current histogram" >} > Others have already helped with the direct questions you raised. I think it important to add that you might be most satisfied in the long term to concentrate on doing as much as possible in Tcl; if I understand you correctly, there's no *functional* need to resort to C as this example does. If your aim is to learn the C interface, rather than achieve particular algorithms, then, of course, we'll help you learn the C interface.
* "maura.monville@gmail.com" <maura.monville@gmail.com> Whenever you write TCL code such as if {[some_c_routine]} { ... } you implicitly assume that the routine returns TCL_OK, and the interpreter result of calling the C routine is some boolean value. If your C-code returns TCL_ERROR, the 'if' will not run at all, but TCL will abort execution the proc containing that code. So if you need the C code simply to determine yes/no, you would do it like this: static int check_hist_aint_option_cb( ... ) { // default result is false int result = 0; // check our data structures if ( hg.active_ > 0 ) { for (int i = 0; i < Length_of_AINT_histo_ID; ++i) { if (hg.hid_ == AINT_histo_ID[i]) { // found something, result is true result = 1; break; } } } // set the result of calling this routine from TCL Tcl_SetObjResult(interp, Tcl_NewBooleanObj(result)); // tell TCL we have performed our task succesfully return TCL_OK; } | My C routine checks the validity of a selected option for the | currently displayed histogram. Therefore it returns a Boolean value | that, according to the C <-> Tcl communucation protocol, I have | encoded as TCL_ERROR (= FALSE) and TCL_OK (TRUE). Returning TCL_ERROR or TCL_OK are meant as a means for TCL to find out whether or not the C code has performed it's task successfully. Returning TCL_ERROR or TCL_OK is *not* the result you will see in the TCL code. R'
In article <k2ngk3-fio.ln1@lairds.us>, I advised: >In article <1148531359.044694.114430@j33g2000cwa.googlegroups.com>, >maura.monville@gmail.com <maura.monville@gmail.com> wrote: >>I've ventured on creating a Tcl command trough a C routine. I've >>followed the manual guidelines. > . > . > . >Others have already helped with the direct questions you raised. >I think it important to add that you might be most satisfied in >the long term to concentrate on doing as much as possible in Tcl; >if I understand you correctly, there's no *functional* need to >resort to C as this example does. > >If your aim is to learn the C interface, rather than achieve >particular algorithms, then, of course, we'll help you learn the >C interface. I'm going to repeat myself. Maura, I'm posting this as a follow-up in comp.lang.tcl, and sending you a copy to your personal e-mail address. You wrote me in personal e-mail "I feel much more comfortable with C and C++ and the traditional debuggers that apply to compiled code. Moreover, if I need to use a math function like log10, cos, exp, etc ... I could not find any of these features in the Tcl library ...." I think you're making a mistake. I understand that you're looking for the quickest, most certain way to achieve results in a situation where your project lead is accustomed to ... treating software development as unskilled, mismnaged, fungible labor. I understand that you have considerable experience working with C and related languages and the debuggers common in their use. Tcl puzzles you, and you've been assigned a base of source code which apparently was generated by a confused mis-automation. It's easy to sympathize with your decision to do as much work as possible in C, rather than Tcl. I can assure you that I, and several other contributors here, have even more experience living through very similar situations. I have repeatedly been on teams that were more comfortable in C than Tcl--several times, *I* was one of the programmers who felt that way. From everything I know, you're better off learning the relatively modest amount of Tcl you need to know to achieve the results you're after. I particularly emphasize: I've seen the experiment where someone says, "I know how to do this in C, so I'll just write a little C-Tcl interface, and that'll be quicker." I've seen multiple trials of that experiment. They really don't work out that way. By the time the person knows Tcl well enough to communicate cor- rectly with the C side, he or she can typically write in pure Tcl. There's no gain. (Note to other readers: there definitely are cases where *teams* can divide labor so that one person concentrates on C. That is not Maura's situation.) Finally, I'll transcribe a tclsh session that might interest you: % expr exp(1) 2.71828182846 % expr log(100.01) 4.60527018099 % expr log10(100.01) 2.00004342728 % expr cos(3.14) -0.999998731728 I summarize, again: I strongly suspect you'll find the most ultimate satisfaction in learning enough of Tcl to code pure-Tcl solutions to your tasks--or perhaps just to receive fragments that others of us write.