[REBOL] Re: callbacks
From: moliad:gma:il at: 29-Oct-2007 20:21
ATTENTION:
This is a report about a bug I am having with the callback system within
rebol. Your experience may be different, but this just happened to me. Its
good to know, so I am posting this on the Mailing list, so someone searching
about callbacks might find it.
its a long and detailed post, sorry, but this just couldn't be explained
properly within a simple 3 line post without quite a few questions popping
up .
note, the code below is simplified and does not run by itself, it just
illustrates the exact problem without clutter.
here we go:
this code (the extended version of this code) crashes whenever the func-a is
called by the external lib!
;-----------------------------------------------
rebol []
my-lib: load/library %some-bogus-lib
do-init: make routine! [
"pass the supplied arguments as callbacks to lib."
number [long] "this shall always be set to 0 (void* = NULL)"
spec-a [callback [long ]]
spec-b [callback [char]]
spec-c [callback [char*]]
] my-lib "doInit"
func-a: func [value [integer!]][print value]
func-b: func [letter [char!][print letter]
func-c: func [sentence [string!]][print sentence]
do-init 1 :func-a :func-b :func-c
;-----------------------------------------------
I was getting an "illegal memory read at address 0x00000001", hard core
windows crash. (but thankfully not a blue screen :-)
I thought I had my callbacks in bad order, but no, it would effectively fire
off the wrong callbacks if I changed the order supplied to do-init, so I had
to put things back... I was a bit stumped.
then I looked at the address MS was giving me... hum ...the number looked
too clean... like an enum value, so I could figure out a callback value
actually was being supplied somewhere.
I tried many things, tripple-checked everything but finally, to have the
code working, I had to switch the callback specs, without changing the
actuall callback submission order, cause remember, its actually calling the
proper callback function itself!
what's happening, is that its in fact (for some VERY ODD reason) using
spec-c and being a pointer to string, its trying to reference mem addres at
value!
within the lib, func-a really IS being called, its just REBOL which is
trying to apply the wrong trampoline specification, in order to convert the
mem address into a rebol string. Cause in fact, func-a shouldn't be
referecing the address, it should just use the integer directly and supply
that to func-a.
the above illustrates the change relative to the example above.
;-----------------------------------------------
rebol []
my-lib: load/library %some-bogus-lib
do-init: make routine! [
"pass the supplied arguments as callbacks to lib."
number [long] "this shall always be set to 0 (void* = NULL)"
spec-c [callback [char*]]
spec-b [callback [char]]
spec-a [callback [long ]]
] my-lib "doInit"
func-a: func [value [integer!]][print value]
func-b: func [letter [char!][print letter]
func-c: func [sentence [string!]][print sentence]
do-init 1 :func-a :func-b :func-c
;-----------------------------------------------
so beware, there is some oddity with the callback system.
now I'm about to use Ladislav's get-mem powertool, cause I am receiving
variable length arrays of varying types.. :-)
I should be having loads of fun tonight :-)
-MAx