Ah, you're right. I'm still acclimated to BC here. Disregard! On 5/14/21 7:30 AM, Paulo Matos wrote: > > Sage Gerard writes: > >> I ran into this issue with rsound. I'm not sure how standard output can >> be directly captured from a lower-level language in a Racket context >> when that language can freely ignore the Racket printer and write >> directly to STDOUT within the same operating system process. >> >> I'd hate to just add a "me too", but the only way quick way I could >> think to handle that was to add another subprocess. If I were wanting to >> solve the problem in one process, I'd probably extend Racket at the C >> level and integrate my output with ports. >> >> https://docs.racket-lang.org/inside/Ports_and_the_Filesystem.html?q=c%20api > I was thinking about this until I saw Jon's suggestion - specific to > binaryen bindings. > > However, why would you use the C API (which seems to be mostly focused > on BC)? My approach would be to wrap the function in C, redirect stdout > using dup2 to a file and bind that wrapper in racket, read from the file > and send to `current-output-port`. > > Kind regards, > > Paulo Matos > >> On 5/12/21 3:48 AM, Paulo Matos wrote: >>> Hi, >>> >>> I have a shared library for which I am creating some bindings: >>> https://github.com/pmatos/racket-binaryen >>> >>> There's a function BinaryenModulePrint that prints a WebAssembly module >>> to stdout. >>> >>> When I wrap it in racket, if I do something like: >>> (define mod ...) >>> (with-output-to-string (lambda () (BinaryenModulePrint mod))) >>> >>> The return value will be "" and it will still print the module to >>> stdout. I understand! However, I don't know how to solve it in Racket. >>> >>> In C, things seem easier because I have access to dup2 and pipe in case >>> I need to redirect things, however in Racket all my attempts have >>> failed. >>> >>> I have created the simple example: >>> ```hello.c >>> #include <stdio.h> >>> >>> void hello(void) { >>> printf("hello world!\n"); >>> } >>> ``` >>> >>> Compile with `gcc -shared -o hello.so hello.c`. >>> >>> Then: >>> ```hello.rkt >>> #lang racket/base >>> >>> (require racket/port >>> ffi/unsafe >>> ffi/unsafe/define) >>> >>> (define libhello (ffi-lib "/home/pmatos/dev/tmp/ffi-hello-world/hello.so")) >>> (define-ffi-definer define-hello libhello) >>> (define-hello hello (_fun -> _void)) >>> (with-output-to-string hello) >>> ``` >>> >>> Here's the issue! In C, I can do something like: >>> ```hello-fix.c >>> #include <stdio.h> >>> #include <unistd.h> >>> #include <sys/stat.h> >>> #include <fcntl.h> >>> >>> extern void hello(void); >>> >>> int main(void) { >>> int filefd = open("test.txt", O_WRONLY|O_CREAT, 0666); >>> dup2(filefd, fileno(stdout)); >>> hello(); >>> >>> return 0; >>> } >>> ``` >>> Compile with `gcc -o hello hello.c hello-fix.c` >>> >>> This will, send the output of hello() to a file. Now, in racket >>> preferably I want to connect what is sent to raw stdout, fd 1, to >>> current-output-port. >>> >>> My thought was that I could create a dup2 ffi binding, and use >>> unsafe-port->file-descriptor to install the racket pipe file descriptor >>> in stdout using the dup2 ffi binding but it doesn't work. >>> >>> And it doesn't work because the unsafe-port->file-descriptor returns #f, >>> even though port-waiting-peer? return #f as well (which sort of hints >>> that maybe the documentation of unsafe-port->file-descriptor is >>> incomplete. >>> >>> The start of my attempt would look like this: >>> >>> ```hello.rkt >>> #lang racket/base >>> >>> (require racket/port >>> ffi/unsafe >>> ffi/unsafe/define >>> ffi/unsafe/port) >>> >>> (define libhello (ffi-lib "/home/pmatos/dev/tmp/ffi-hello-world/hello.so")) >>> >>> (define-ffi-definer define-libc (ffi-lib #f)) >>> (define-ffi-definer define-hello libhello) >>> >>> (define-libc dup2 (_fun _int _int -> _int)) >>> (define-hello hello (_fun -> _void)) >>> >>> (define-values (in out) (make-pipe)) >>> >>> ;; FAILS because (unsafe-port-> ...) return #f >>> (dup2 (unsafe-port->file-descriptor out) 1) >>> >>> ;;... >>> ;; connect the other end of the port to current-output-port >>> ;; and use a thread to copy-port >>> ``` >>> >>> Surely there must be a better way than this and I would be surprised if >>> there isn't already something out there in a library but I haven't found >>> anything yet. Any help here would be great. >>> >>> Thanks, >>> >>> -- >>> Paulo Matos >>> >>> -- >>> 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 [email protected]. >>> To view this discussion on the web visit >>> https://groups.google.com/d/msgid/racket-users/87r1icxuhi.fsf%40linki.tools. >> -- >> ~slg > > -- > Paulo Matos
-- ~slg -- 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 [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/1549d35d-93b8-8fdd-498c-2ff694746b00%40sagegerard.com.

