下面是一个golang程序,它调用一个输出到stderr
的C函数。在真实的的程序中,函数调用在一个我无法更改的库中:
package main
// #include <stdio.h>
// #include <stdlib.h>
//
// // assume that we cannot change this function
// static void library_call(char* s) {
// fprintf(stderr, "%s\n", s);
// }
import "C"
import (
"fmt"
"io"
"os"
"unsafe"
)
func main() {
// attempt to redirect os.Stderr to write to a pipe; it does prevent
// writing to stderr, but does not successfully capture the output
r, w, _ := os.Pipe()
_ = os.Stderr.Close()
os.Stderr = w
// call a C function that writes to stderr; I would like to capture this
// output in a buffer
cs := C.CString("This should be the contents of the buffer")
C.library_call(cs)
C.free(unsafe.Pointer(cs))
// the pipe will capture this output if you uncomment it
// fmt.Fprintf(os.Stderr, "testing")
// close the pipe writer, so we can read from it
w.Close()
// Question: how would I restore os.Stderr here to its normal value?
out, _ := io.ReadAll(r)
// I'd like this to output
// "got output: This should be the contents of the buffer",
// but it's empty instead
fmt.Printf("got output: %s\n", string(out))
}
(You可以将其保存到test.go
并编译和运行它:go build test.go && ./test
)
我想做的是在缓冲区中捕获C.library_call
的输出(它写入stderr),然后在调用完成后将os.Stderr
恢复到其正常功能。
我不知道怎么做,你能帮我吗?
(For加分,这也应该在windows上工作!)
1条答案
按热度按时间gr8qqesn1#
我找到了code from Eli Bendersky on github和一个accompanying article,它帮助我找到了解决方案,至少在unix上是这样。我很确定这在Windows上不起作用:
这让我走得更远,但如果你知道如何解决这个问题的Windows太(或这将工作在Windows上?)那就太好了!