Golang中如何传递C语言头文件目录给go build

Golang中如何传递C语言头文件目录给go build 我正在尝试封装一个C语言库以便在Go中使用。

我已经有了一个有效的SWIG .i文件,并且已经执行到以下步骤:

go mod init skirmish-dev.net/sgd
swig -go -I../include sgd.i
go build

…这时我遇到了一个错误:

sgd_wrap.c:211:10: fatal error: sgd/sgd.h: No such file or directory
  211 | #include <sgd/sgd.h>

问题似乎在于,我没有像传递给swig命令那样,将sgd/sgd.h的头文件包含目录传递给go build。我尝试过在go build中使用-Iblah参数,但它报错了。

我也尝试过用gcc编译由swig生成的sgd_wrap.c文件,但它无法构建,实际上它看起来不像有效的C代码。

有没有办法将包含目录传递给go build,或者有没有其他方法来构建sgd_wrap.c文件?

你可能已经猜到了,我对Go非常陌生!

再见。


更多关于Golang中如何传递C语言头文件目录给go build的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

在Go中传递C头文件目录给go build需要使用cgo的编译指令。你需要在Go源文件中使用#cgo指令来指定头文件路径。

在你的Go文件中(可能是包含SWIG生成代码的文件),添加以下指令:

/*
#cgo CFLAGS: -I../include
#include "sgd_wrap.c"
*/
import "C"

或者,如果你有多个包含目录:

/*
#cgo CFLAGS: -I../include -I/path/to/other/include
#include "sgd_wrap.c"
*/
import "C"

如果你使用的是Go模块,还可以在go.mod文件中添加构建约束:

// go.mod
module skirmish-dev.net/sgd

go 1.xx

require (
    // 你的依赖
)

// 添加构建指令
replace (
    // 如果有需要替换的模块
)

// cgo构建指令
// +build cgo

另一种方法是通过环境变量设置:

export CGO_CFLAGS="-I../include"
go build

或者直接在一行命令中:

CGO_CFLAGS="-I../include" go build

如果你的C库需要链接库文件,还需要添加LDFLAGS:

/*
#cgo CFLAGS: -I../include
#cgo LDFLAGS: -L/path/to/libs -lsgd
#include "sgd_wrap.c"
*/
import "C"

对于SWIG生成的文件,确保你的Go文件正确引用了SWIG包装器。典型的SWIG生成结构如下:

// main.go 或你的Go文件
package main

// #cgo CFLAGS: -I../include
// #include "sgd_wrap.c"
import "C"

func main() {
    // 使用SWIG生成的函数
}

如果问题仍然存在,检查SWIG生成的sgd_wrap.c文件是否在正确的目录中,以及头文件路径是否正确。

更多关于Golang中如何传递C语言头文件目录给go build的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


好的,我尝试将头文件复制到与模块相同的目录中,现在进展了一些,但 go build 失败了,报错与我尝试使用普通 gcc 构建时遇到的错误相同。以下是其中一些错误,但总共有数百个…

In file included from sgd_wrap.c:179:
c:\users\marks\dev\mingw\x86_64-w64-mingw32\include\string.h:50:45: note: expected 'void * restrict' but argument is of type 'SGD_String' {aka 'const char *'}
   50 |   void * __cdecl memcpy(void * __restrict__ _Dst,const void * __restrict__ _Src,size_t _Size) __MINGW_ATTRIB_DEPRECATED_SEC_WARN;
      |                         ~~~~~~~~~~~~~~~~~~~~^~~~
sgd_wrap.c:1895:22: error: assignment of read-only location '*(arg1 + (sizetype)_swig_go_0.n)'
 1895 |   arg1[_swig_go_0.n] = '\0';
      |                      ^
sgd_wrap.c:1901:8: warning: passing argument 1 of 'free' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
 1901 |   free(arg1);
      |        ^~~~
In file included from sgd_wrap.c:178:
c:\users\marks\dev\mingw\x86_64-w64-mingw32\include\stdlib.h:536:27: note: expected 'void *' but argument is of type 'SGD_String' {aka 'const char *'}
  536 |   void __cdecl free(void *_Memory);
      |                     ~~~~~~^~~~~~~
sgd_wrap.c: In function '_wrap_LoadSkybox_sgd_f7b3eb29aefada5b':
sgd_wrap.c:1984:10: warning: passing argument 1 of 'memcpy' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
 1984 |   memcpy(arg1, _swig_go_0.p, _swig_go_0.n);
      |          ^~~~
回到顶部