c - 将 FILE 指针传递给 C 函数
问题描述
我的 C 函数获取 FILE 指针的地址(指向指针的指针,即FILE **fp
)。我从 Go 调用这个方法。有人可以给我一个在 Go 中调用约定的示例代码行吗?
C 库代码(将创建.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");
}
解决方案
您可以从 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)
}
推荐阅读
- java - Java 电子邮件中的 HTML 格式文本
- python - Pygame 和 Numpy 动画
- java - 将用户输入存储到变量中
- php - 限制在 Woocommerce 产品类别档案中显示的产品
- ios - 使用 Swift 在谷歌地图中获取位置详细信息
- angular - 带有列表的 Angular 7 材质选项卡控件
- identityserver4 - 带有单独登录屏幕的 IdentityServer4
- objective-c - 从firebase db中删除孩子时如何观察
- css - 如何在Angular7中全局设置字体大小(将自定义值设置为rem)?
- optimization - 半定整数规划库