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 racket-users+unsubscr...@googlegroups.com.
>>> 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 racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/1549d35d-93b8-8fdd-498c-2ff694746b00%40sagegerard.com.

Reply via email to