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.

Reply via email to