[racket] Some problem with hash-update!
I think that changing `_pointer` to `_DWORD` can't be the real answer,
since `_pointer` is at least as large as `_DWORD`.
But I agree that you should use `malloc`, and you should also supply
'atomic-interior:
(malloc _DWORD 'atomic-interior)
The 'atomic-interior flag ensures that the allocated memory does not
move during an invocation of the callback.
Along similar lines, I think you need to add
#:malloc-mode 'atomic-interior
to the declaration of `_CMN_ERROR`.
You may need to copy the `filter` argument into non-moving memory, but
that's probably not an issue if it's always "".
At Mon, 15 Sep 2014 11:07:52 +0700 (NOVT), "Evgeny Odegov" wrote:
> More complete example:
> http://pasterack.org/pastes/25901
>
> I guess I've found reason of the problem.
>
> I think the problem was in that line:
> (define lpdwItems (make-bytes (ctype-sizeof _pointer) 0))
>
> I've changed it to:
> (define lpdwItems (make-bytes (ctype-sizeof _DWORD) 0))
>
> There is no visible problems now, but I doubt that applying `make-bytes'
> here is right.
>
> Should I use `malloc' in such cases?
>
>
> Anyway, sorry for the noise.
>
>
> > My best guess is that it's an issue with memory management, because
> > memory management gets a lot trickier when you call a function that can
> > call back into Racket. A GC can happen during the callback, and
> > therefore during the dynamic extent of the foreign-function call, which
> > can move arguments that were passed to the foreign function, for example.
> >
> > Would it be possible to provide a complete example?
> >
> > At Sat, 13 Sep 2014 22:45:28 +0700 (NOVT), "Evgeny Odegov" wrote:
> >> Oh, I'm wrong. The last code is not equivalent to initial.
> >> The equivalent code has this problem:
> >>
> >> (define result (make-hash))
> >> (define big-list (list))
> >> (define (callback dwTextID lpszInfoText lpvUser)
> >> (if (equal? lpszInfoText "")
> >> (set! big-list (append big-list (list dwTextID)))
> >> (hash-update! result
> >> lpszInfoText
> >> (lambda (id-lst)
> >> (define v (list dwTextID))
> >> (append id-lst v))
> >> '()))
> >> #t)
> >>
> >>
> >> The code with `cons' instead `append' works fine:
> >>
> >> (define result (make-hash))
> >> (define (callback dwTextID lpszInfoText lpvUser)
> >> (hash-update! result
> >> lpszInfoText
> >> (lambda (id-lst)
> >> (define new-id-lst (cons dwTextID id-lst))
> >> (unless (list? new-id-lst)
> >>
> >> (error "~v" new-id-lst))
> >> new-id-lst)
> >> '())
> >> #t)
> >>
> >>
> >>
> >>
> >> ____________________
> >> Racket Users list:
> >> http://lists.racket-lang.org/users
> >