I think I haven't run into this because `r` and `foo` are usually
combined into one value that's more Rackety. Maybe `allocator` should
have a `get-result` optional argument similar to `deallocator`.

Meanwhile:

 ;; Not exported:
 (define-fooapi make_foo
   (_fun (foo : (_ptr o _foo))
         -> (r : _int)
         -> (values r foo)))

 ;; Not exported:
 (define made-foo ((allocator destroy-foo) (lambda (foo) foo)))

 ;; Exported:
 (define (make-foo)
   (start-atomic)
   (let-values ([(r foo) (make_foo)])
     (made-foo foo)
     (end-atomic)
     (values r foo)))

With Dmitry's solution as written, you don't get atomicity of the
foreign function producing a result and registering it, if that
matters. But you could use `#:wrap` to add a `call-as-atomic` wrapper.
(That doesn't let you call the destructor more eagerly, though.)

At Wed, 24 Jan 2018 22:53:41 +0300, Dmitry Pavlov wrote:
> Konrad,
> 
> I would create a wrapper like this:
> 
> (define-fooapi make-foo
>       (_fun (foo : (_ptr o _foo)
>              -> (r : _int)
>              -> (if r (begin (register-finalizer-and-custodian-shutdown foo 
> destroy-foo) foo)
>                      (error "can not make foo")))
> 
> 
> Regards,
> 
> Dmitry
> 
> On 01/24/2018 10:47 PM, Konrad Hinsen wrote:
> > Hi everyone,
> >
> > I am working on an FFI which overall progresses well - the Racket FFI 
> library is really a very nice tool to have.
> >
> > The one problem I couldn't solve yet is handling resource allocation. My 
> > use 
> case is very similar to what allocator/deallocator are meant for, except that 
> the allocated object is not the return value of any function, and therefore I 
> cannot use allocator.
> >
> > I have an API like
> >
> >    int make_foo(foo** new_foo);
> >    int destroy_foo(foo* a_foo);
> >
> > so my FFI definitions look like
> >
> >   (define _foo (_cpointer 'foo))
> >
> >   (define-fooapi make-foo
> >      (_fun (foo : (_ptr o _foo)
> >             -> (r : _int)
> >             -> (values r foo))
> >
> >   (define-fooapi destroy-foo
> >      (_fun _foo -> _void))
> >
> > Given that make-foo returns two values, I cannot use #:wrap to make it an 
> allocator.
> >
> > Since the C API I am wrapping is pretty standard, I suspect others have had 
> this problem before. Any suggestions?
> >
> > Thanks in advance,
> >   Konrad.
> >
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to