There are a few issues with your code. First of all, you should use “___return(…);” to return a result (the assignment to ___result_voidstar is deprecated). When Scheme code receives a foreign pointer, there is no “automatic freeing” of the memory done by Gambit. You need to program that explicitly, for example using a will. An alternative would be to create your own type with a release function, but that is probably overkill in this situation. Here’s how I would write the code:
(c-declare "#include <stdlib.h>") (c-declare "#include <sys/socket.h>")
(c-define-type sockaddr_storage (struct "sockaddr_storage")) (c-define-type socket-address (pointer sockaddr_storage socket-address))
(define alloc-socket-address (c-lambda () socket-address "___return(malloc(sizeof(struct sockaddr_storage)));"))
(define free-socket-address (c-lambda (socket-address) void "free(___arg1);"))
(define (make-socket-address) (let ((sa (alloc-socket-address))) (if sa (make-will sa (lambda (sa) (pp (list 'freeing sa)) (free-socket-address sa)))) sa))
(println "-----------") (pp (make-socket-address)) (define foo (make-socket-address)) (pp foo) (println "-----------") (##gc) (println "-----------") (pp (make-socket-address)) (println "-----------") (##gc) (println "-----------")
;; prints: ;; ;; ----------- ;; #<socket-address #2 0x7fe723405010> ;; #<socket-address #3 0x7fe7234050f0> ;; ----------- ;; (freeing #<socket-address #2 0x7fe723405010>) ;; ----------- ;; #<socket-address #4 0x7fe723405010> ;; ----------- ;; (freeing #<socket-address #4 0x7fe723405010>) ;; -----------
Marc
On Apr 10, 2020, at 3:12 PM, Jörg F. Wittenberger Joerg.Wittenberger@softeyes.net wrote:
Hi,
I'm afraid I don't grock the documentation wrt. memory management of foreign bjects.
I really need a unix domain socket. Actually an abstract socket on Linux.
The example at at hand: a `struct sockaddr_storage`. That is, in general, any kind of C struct to allocate.
Likely I'm doing it all wrong. My great excuse(TM): I learned gambit's FFI from `gamsock` while adding domain socket support. No, Mam, it's not been me. ;-)
# Part I, the easy thing
(c-define-type socket-address (pointer (struct "sockaddr_storage") socket-address))
(c-lambda (...) socket-address "... ___result_voidstar = malloc(sizeof(struct sockaddr_storage))); ...")
That seems to work. But I'd bet this leaks memory as gamsock never frees this memory.
Q: Does it leak? Or is there some gambit magic default?
# Part II, the crazy thing
If I got that right, than what I'd need to fix the leak was to attach a /will/ to the socket-address, which would free the storage and return ___NO_ERR.
Q: Correct?
If yes, is this a good idea? I'd assume that allocating short lived objects from the Scheme heap should be much less expesive. Isn't it?
# Part III, how?
- How would I allocate a short lived object on the scheme heap?
- Still have it properly tagges as foreign object for type checking.
(I.e., I know I could allocate a u8vector of the size I need. But this is an u8vector for Scheme, which I don't want.)
Thanks
/Jörg
Gambit-list mailing list Gambit-list@iro.umontreal.ca https://mailman.iro.umontreal.ca/cgi-bin/mailman/listinfo/gambit-list