英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论