将sqlite.c嵌入到Go代码中:ld在不应该的情况下抱怨libdl。

huangapple go评论92阅读模式
英文:

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 an import () 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.

huangapple
  • 本文由 发表于 2022年7月1日 20:07:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/72829037.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定