How to create Libc.FILE from a string

I’m looking for a solution to the following problem:
A function in c takes a FILE *rfile argument. If i want to read file I can do

open(filename, "r") do file_hdlr
    c_file_hdlr = Libc.FILE(file_hdlr)
    # ccall with c_file_hdlr as Ptr{Cvod}
end

however sometimes I have the content of the input file as a String and I’d like to avoid writing files e.g. as:

S = "abc"
open(tempname(), "rw") do file_hdlr
    write(file_hdlr, S)

    c_file_hdlr = Libc.FILE(file_hdlr)
    seek(c_file_hdlr, 0)
    # ccall with c_file_hdlr as Ptr{Cvod}
end

Question as in title: how to create Libc.FILE from String without writing to a temp file?

I don’t believe there is a generic way of doing this. If you are on linux then I would look into the C library call mkfifo to create a named pipe. Then in Julia (on another thread or maybe in an async task) you open it for writing and write the string. The on your main execution path you open it for reading and pass it to the external library.

To elaborate a bit on why this can’t be done, the trouble is that FILE is an opaque structure that each libc is free to implement however it wants. Julia’s IO handles, on the other hand, are wrappers around libuv file handles and do not correspond to libc FILE handles. They do contain raw int file descriptors somewhere, but getting those out in a generic way is not straightforward either. The fifo approach seems like a good one.

1 Like

@StefanKarpinski thanks for the answer;
we will then first try to modify the c code (but it’s a mangled spaghetti monster:).

Julia IO object, if you includes ones that you can wrap a string in, does not necessarily have a corresponding file descriptor.

Now if you are talking about writing platform specific versions, you can go with fmemopen or open_(w)memstream to construct a FILE* from a string directly.

You also don’t need a named fifo. You can just create an anonymous one (pipe) and you can get the corresponding reader end with fdopen.

2 Likes