Definition: |
include pGUI.e
atom res = IupRawStringPtr(string s) |
Description: | Utility function. Returns a raw pointer to a string, like allocate_string() but using the existing memory. |
Comments: |
The result is only valid as long as the argument still exists. In effect it creates a non-reference-counted reference, and that requires it to
be carefully managed. In particular the results of sprint and sprintf should not be used directly, and callbacks must make a semi-permanent copy
somewhere other than locals/temps. It is in fact callbacks that have the most obvious need for such a function.
In the example below, if semiperm were local to the value_cb routine, it would be freed (and the first few bytes clobbered) by the return statement, before the caller had a chance to inspect it. Likewise any hidden unnamed temp (of the sole reference variety). Obviously if data[l][c] is a string, then it is fine to return IupRawStringPtr(data[l][c]), that is assuming data persists when value_cb returns. There may be some cases where the fact that semiperm is clobbered on the very next call of value_cb may cause issues, in which case a more complex stack of allocate_string() may need to be kept, but offhand I cannot think of any, or at least any that would be used with pGUI. It may help to understand the differences between IupSetAttribute (where these kinds of problems may well arise) and IupSetStrAttribute (where they do not). I should also note that using the optional automatic memory management flag of allocate_string is equally incorrect and inappropriate for callback returns, for exactly the same reason, unless you use something like atom semiperm in a similar fashion to that below. Apart from that, should you experience any problems with IupRawStringPtr, such as semiperm being non-thread-safe, then instead by all means try using allocate_string() with a manual free() at some appropriately later time. |
Example: |
include pGUI.e sequence data = {{1,11.17}, {2, 7.54}, {3,15.35}} string semiperm -- (return of value_cb must outlive the call) function value_cb(Ihandle self, integer l, integer c) -- (if l or c out of range then return NULL end if) semiperm = sprint(data[l][c]) -- or expr using &, [..], etc return IupRawStringPtr(semiperm) end function ... IupSetCallback(matrix,"VALUE_CB",Icallback("value_cb")) ... |
See Also: | allocate_string, IupSetAttribute, IupSetStrAttribute, IupSetCallback, Icallback |