Golang中无法访问包含C代码的文件夹如何解决

Golang中无法访问包含C代码的文件夹如何解决 当我导入一个包含.cpp文件的文件夹时,收到一条消息

程序结构

 src/main
|
| ccode      (这是一个C文件夹)
   * c1.cpp
   * c1.h
   * c2.cpp 

| gocode	    (这是一个Go文件夹)
        | headers 
          * h1.go
          * h2.go
        | maingofile.go
               (在 maingofile.go 中,我尝试导入 ccode )

maingofile.go

package gocode

#import C import “main/ccode”

当我导入 “main/ccode” 文件夹时,看到的错误信息是:

"package main/gocode imports ccode: no Go files in /home/user/go/src/ccode go "

问题是什么? 谢谢


更多关于Golang中无法访问包含C代码的文件夹如何解决的实战教程也可以访问 https://www.itying.com/category-94-b0.html

4 回复

amelia: 我会尽量让我的问题与Go相关。

我并非有意让你离开。只是想提供一个你可能没有考虑过的替代方案!我们仍然会尽最大努力帮助你解决cgo问题!

更多关于Golang中无法访问包含C代码的文件夹如何解决的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


确实,@skillian,我正在开发 Go 项目,同时还有一些现有的 C++ 项目需要通过 Go 来调用,而不是重新开发。

我只是想寻求关于如何从 Go 调用 C 或者需要开发哪些包装器的帮助。

我会尽量让我的问题与 Go 相关。

这个链接很有帮助:https://github.com/mattn/go-sqlite3

我认为你不能有一个单独的C语言文件夹。在我看到的少数使用cgo的地方,它似乎是.c文件和.go文件中import "C"语句上方注释中的“内联”C代码的组合。例如,我在谷歌搜索“cgo项目示例”后找到的两个:

请允许我提个观察:在你的第一个问题这里,你说你正在做你的第一个项目并且它是“用Go写的”,然而你所有的问题都是关于如何从Go引用C或C++代码。这些C/C++代码到底是什么?花一个月的时间来弄清楚如何从Go中使用它,而不是直接学习并将其重写成Go,真的值得吗?答案当然可能是“是的”,但我想我还是问一下。这个论坛上的大多数回答者更倾向于回答关于如何用纯Go而不是cgo来做事情的问题。

这是一个典型的Go与C混合编译问题。错误信息表明Go工具链在ccode目录中找不到任何.go文件,因此无法将其识别为有效的Go包。

解决方案:

您需要在ccode目录中创建一个Go文件,使用cgo指令来链接C代码。以下是正确的实现方式:

程序结构调整:

src/main/
├── ccode/
│   ├── c1.cpp
│   ├── c1.h
│   ├── c2.cpp
│   └── ccode.go      ← 新增的Go包装文件
└── gocode/
    ├── headers/
    │   ├── h1.go
    │   └── h2.go
    └── maingofile.go

ccode/ccode.go 文件内容:

// 必须包含这个空包声明
package ccode

/*
#cgo CXXFLAGS: -std=c++11

// 包含C++头文件
#include "c1.h"
#include <stdlib.h>
*/
import "C"

// 导出Go函数包装C++函数
func CallCppFunction() {
    // 调用C++函数(假设c1.h中有相关声明)
    C.cpp_function_from_c1()
}

// 处理字符串参数的示例
func ProcessString(input string) string {
    cstr := C.CString(input)
    defer C.free(unsafe.Pointer(cstr))
    
    result := C.process_string(cstr)
    return C.GoString(result)
}

maingofile.go 文件内容:

package main

import (
    "main/ccode"
    "fmt"
)

func main() {
    // 现在可以正常导入和使用ccode包
    ccode.CallCppFunction()
    
    result := ccode.ProcessString("Hello from Go")
    fmt.Println(result)
}

关键点说明:

  1. cgo指令:在Go文件中使用/* */注释包含C/C++代码和编译指令
  2. import “C”:必须紧跟在C代码注释之后,这是一个特殊的伪包
  3. C.CString和C.GoString:用于Go字符串和C字符串之间的转换
  4. 内存管理:使用C.mallocC.CString分配的内存需要用C.free释放

C++头文件示例 (c1.h):

#ifdef __cplusplus
extern "C" {
#endif

void cpp_function_from_c1();
const char* process_string(const char* input);

#ifdef __cplusplus
}
#endif

编译命令:

# 设置CGO_ENABLED(默认已启用)
export CGO_ENABLED=1

# 编译项目
go build main/gocode

这样配置后,Go工具链就能正确识别ccode包,并通过cgo机制链接您的C++代码。

回到顶部