英文:
Embedding sqlite.c into Go code: ld complains about libdl while it should not
问题
我对CGo完全不熟悉。我不想使用mattn的go-sqlite包,而是想构建自己的最小化SQLite接口。
我试图在我的Linux机器上使用go build编译最简单的程序,但总是返回相同的错误:
/usr/bin/ld: $WORK/b001/_x003.o: 在函数 `unixDlError' 中:
./sqlite3.c:42036: 对 `dlerror' 未定义的引用
/usr/bin/ld: $WORK/b001/_x003.o: 在函数 `unixDlClose' 中:
./sqlite3.c:42067: 对 `dlclose' 未定义的引用
/usr/bin/ld: $WORK/b001/_x003.o: 在函数 `unixDlSym' 中:
./sqlite3.c:42063: 对 `dlsym' 未定义的引用
/usr/bin/ld: $WORK/b001/_x003.o: 在函数 `unixDlOpen' 中:
./sqlite3.c:42022: 对 `dlopen' 未定义的引用
collect2: error: ld 返回 1 退出状态
项目布局如下:
- go.mod
- main.go
- sqlite3.c
- sqlite3.h
main.go 的内容如下:
//go:build cgo
// +build cgo
package main
/*
#cgo CFLAGS: -DSQLITE_OMIT_LOAD_EXTENSION
#cgo CFLAGS: -DSQLITE_THREADSAFE=1
#include "sqlite.h"
*/
import "C"
func main() {
}
我正在使用Go 1.18.1。
非常感谢任何帮助或指引!
英文:
I'm absolutely new to CGo. I don't want to use mattn's go-sqlite package and would like to build my own minimal interface to SQLite.
I'm trying to get compiled the simplest program on my linux machine with go build, and it always returns the same error:
/usr/bin/ld: $WORK/b001/_x003.o: in function `unixDlError':
./sqlite3.c:42036: undefined reference to `dlerror'
/usr/bin/ld: $WORK/b001/_x003.o: in function `unixDlClose':
./sqlite3.c:42067: undefined reference to `dlclose'
/usr/bin/ld: $WORK/b001/_x003.o: in function `unixDlSym':
./sqlite3.c:42063: undefined reference to `dlsym'
/usr/bin/ld: $WORK/b001/_x003.o: in function `unixDlOpen':
./sqlite3.c:42022: undefined reference to `dlopen'
collect2: error: ld returned 1 exit status
The project layout is:
- go.mod
- main.go
- sqlite3.c
- sqlite3.h
The contents if main.go is:
//go:build cgo
// +build cgo
package main
/*
#cgo CFLAGS: -DSQLITE_OMIT_LOAD_EXTENSION
#cgo CFLAGS: -DSQLITE_THREADSAFE=1
#include "sqlite.h"
*/
import "C"
func main() {
}
I'm using Go 1.18.1.
Any help or nudge in the right direction is greatly appreciated!
答案1
得分: 0
要在Go文件中嵌入一些C代码,你需要将C语句写成所谓的“前导语”。关于格式方面有一些严格的规则:
import "C"是一个独立的语句,不能包含在import ()组中- C的包含和其他代码(前导语)紧接着
import "C"语句之前,它们之间不能有空行
所以在你的情况下,你需要像这样写:
package main
// #include "sqlite.h"
import "C"
import (
"fmt"
// 正常的导入语句在这里
)
正如你已经验证的那样:前导语可以是多行注释,所以使用你喜欢的任何一种方式。最重要的是它们与 import "C" 语句之间没有空行。
英文:
To embed some C code inside a Go file, you write the C statements as something called preambles. There are certain strict rules regarding the formatting:
import "C"is a standalone statement, and cannot be included in animport ()group- The C includes and other code (preambles) immediately precede the
import "C"statement, without any blank lines in between
So in your case, what you need is something like:
package main
// #include "sqlite.h"
import "C"
import (
"fmt"
// normal imports here
)
As you have since verified: preambles can be multi-line comments, so use whichever you prefer. The main thing is that there is no blank lines between them and the import "C" statement.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论