package main
/*
#include <stdlib.h>
#include <stdio.h>
void print_string( FILE *stream, char *text) {
printf("Input pointer is %p\n", (void *) stream);
printf("Expected stderr is %p\n", (void *) stderr);
fprintf(stream, text);
}
*/
import "C"
import (
"unsafe"
"syscall"
)
func main() {
text := C.CString("test123\n")
defer C.free(unsafe.Pointer(text))
// fileStream := (*C.FILE)(C.stderr) // this works
fileStream := (*C.FILE)(unsafe.Pointer(uintptr(syscall.Stderr)))
defer C.free(unsafe.Pointer(fileStream))
C.print_string(fileStream, text)
}
抛出访问冲突异常。
我想这样做是因为我想使用 fprintf 的 C 库来处理错误,所以我希望能够创建一个 Go 文件来从中读取错误。
您出现访问冲突错误是因为 Go 的“syscall.Stderr”不是有效的 C FILE 指针。此错误发生的原因是 Go 的系统 call.Stderr 对象不是有效的 C FILE 指针,导致内存访问问题,因为两种类型不兼容。
要创建 GO 文件来读取错误,请考虑以下几点:
修改了C函数print_string:将fprintf替换为snprintf或sprintf,以便在C函数中更安全。 在Go代码中直接传递C.stderr:以C.stderr为流参数直接调用C.print_string,有效地将标准错误流传递给C函数。
如果您需要从其他地方获取错误,您可以重定向 C 库中的标准错误流,并将重定向的流句柄传递给您的 Go 代码。这种方法允许您在 C 库本身内自定义错误处理。