> 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 >> > > ____________________ Racket Users list: http://lists.racket-lang.org/users