CGO 如何转换为 FILE* 类型

问题描述 投票:0回答:1
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 cgo gccgo
1个回答
0
投票

您出现访问冲突错误是因为 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 库本身内自定义错误处理。

© www.soinside.com 2019 - 2024. All rights reserved.