[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`.
Facepalm. Of course, you're right! Somehow, I've thought that _pointer
is twice shorter :)
> 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.
>
It seems like I've got a wrong impression about #:atomic? parameter of
`_fun` form. I thought it's intended to prevent such issues.
> Along similar lines, I think you need to add
>
> #:malloc-mode 'atomic-interior
>
> to the declaration of `_CMN_ERROR`.
>
Thank you for the notes! So, as I see, `malloc' with 'atomic-inferior mode
must be used, when a parameter is changed by foreign function.
> You may need to copy the `filter` argument into non-moving memory, but
> that's probably not an issue if it's always "".
The parameter `lpszFilter` is not changed by `TXTEnumInfoText`.
Is `_string/locale` enough in such case?
What could you say about `_string/locale/len'?
Is there something that I have not took into account?
>
> 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
>> >
>