为了账号安全,请及时绑定邮箱和手机立即绑定

将 FILE 指针传递到 C 函数

将 FILE 指针传递到 C 函数

Go
波斯汪 2022-08-01 17:14:20
我的 C 函数采用 FILE 指针的地址(指向指针的指针)。我从Go调用此方法。有人可以给我一个在Go中调用约定的示例代码行吗?FILE **fpC 库代码(将创建 .so 文件):int fileOpen(char *filename, char* mode, FILE **fp){*fp  = fopen (filename, mode); if (*fp ==NULL)   return -1; return 0;}int fileread(FILE *fp,char *buff ){        if((fp!=NULL)&&( fgets ( buff, 50, fp) != NULL ) )        {                return 0;        }  return -1;}int fileclose(FILE *fp){  fclose(fp);  return 0;}import "C"type (        fileptr C.FILE)func opencfile(name string, mode string) int {        var fp *fileptr        return (int)(C.fileOpen(C.CString(name), C.CString(mode), C.FILE(&fp)));}我收到错误无法将_cgoBase2(类型 **fileptr) 转换为类型 _Ctype_struct__IO_FILE问题:这是调用 C 方法的正确方法吗?如何从Go传递文件指针的地址?或如何解决上述错误。所谓的“C”方法原型是:int fileOpen(char *filename, char* mode, FILE **fp);更新:这是我的最新代码:C 代码(.c 文件)#include "fileOp_lib.h"int fileOpen(char *filename, char* mode, fileptr *out){    FILE *fp  = fopen(filename, mode);    if (fp == NULL) {        *out = 0;        return -1;    }    *out = (fileptr) fp;    return 0;}int fileread(fileptr fp, char *buff){    if( (fp != 0) && (fgets(buff, 50, (FILE*)fp) != NULL) )        return 0;    return -1;}int fileclose(fileptr fp){    fclose((FILE*)fp);    return 0;}头文件(.h 文件)#include <stdio.h>typedef unsigned int fileptr;int fileOpen(char *filename, char* mode, fileptr *out);//int fileread(FILE *fp,char *buff ); temp. commented//int fileclose(FILE *fp);围棋代码package main/*#cgo LDFLAGS: -L./SAMPLE/ -lfileop#include "fileOp_lib.h"*/import "C"type (        fileptr uintptr)func opencfile(name string, mode string) int {        var fp fileptr;        return (int)(C.fileOpen(C.CString(name), C.CString(mode), (&fp)));}func main(){        var e int;        e = opencfile("data.txt","r");}
查看完整描述

2 回答

?
墨色风雨

TA贡献1853条经验 获得超6个赞

与其搞砸更多的层,不如从Go正确调用原始C代码。请参阅 JimB 的评论或下面的示例。


请注意,原始的C代码是...不是很好,而且考虑到除了C代码之外什么都没有,使用Go I / O例程可能会更好,这些例程更安全,更容易正确。想必无论你拥有什么真正的C代码都要复杂得多。您遗漏的部分可能需要对C和Go都有深入的了解才能连接。


下面是编译和运行(并创建一个空)的代码。file.txt


package main


// #include <stdio.h>

// #include <stdlib.h>

// int fileOpen(char *filename, char *mode, FILE **fp) {

//      *fp = fopen(filename, mode);

//      if (*fp == NULL)

//              return -1;

//      return 0;

// }

//

// int fileread(FILE *fp, char *buff) {

//      if ((fp != NULL) && (fgets(buff, 50, fp) != NULL)) {

//              return 0;

//      }

//      return -1;

// }

//

// int fileclose(FILE *fp) {

//      fclose(fp);

//      return 0;

// }

import "C"


import (

        "fmt"

        "unsafe"

)


func opencfile(name string, mode string) (ret int, fp *C.FILE) {

        cname := C.CString(name)

        defer C.free(unsafe.Pointer(cname))

        cmode := C.CString(mode)

        defer C.free(unsafe.Pointer(cmode))

        ret = int(C.fileOpen(cname, cmode, &fp))

        return

}


func main() {

        ret, fp := opencfile("file.txt", "w")

        if ret >= 0 {

                defer C.fileclose(fp)

        }

        fmt.Printf("result of opencfile was %d\n", ret)

}



查看完整回答
反对 回复 2022-08-01
?
30秒到达战场

TA贡献1828条经验 获得超6个赞

我不知道将a从Go传递到C的正确语法(如果可能的话)。但是,如果您可以更改C代码,我建议您不要公开对互操作不兼容类型的直接访问。我会建议更像这样的东西:FILE**FILE


#include <stdint.h>


typedef uintptr_t fileptr;


int fileOpen(char *filename, char* mode, fileptr *out){

    FILE *fp  = fopen(filename, mode);

    if (*fp == NULL) {

        *out = 0;

        return -1;

    }

    *out = (fileptr) fp;

    return 0;

}


int fileread(fileptr fp, char *buff){

    if( (fp != 0) && (fgets(buff, 50, (FILE*)fp) != NULL) )

        return 0;

    return -1;

}


int fileclose(fileptr fp){

    fclose((FILE*)fp);

    return 0;

}

import "C"


...


var fp uintptr

C.fileOpen(..., &fp);

...

c.fileRead(fp, ...);

...

C.fileClose(fp);


查看完整回答
反对 回复 2022-08-01
  • 2 回答
  • 0 关注
  • 151 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信