1

cgo を使用して C から sqlite3 を使用しようとしています (go には sqlite3 ラッパーがあることは知っていますが、この方法を試してみたいと思います)。このプログラムはエラーメッセージを表示します

(Undefined symbols for architecture x86_64:
"_sqlite3_open", referenced from:
  __cgo_1d4838eae1de_Cfunc_sqlite3_open in cGo.cgo2.o
 (maybe you meant: __cgo_1d4838eae1de_Cfunc_sqlite3_open)
 ld: symbol(s) not found for architecture x86_64
 clang: error: linker command failed with exit code 1 (use -v to see invocation)

、理由がわかりません - 新しいデータベースストリームを開く方法を理解するのを手伝ってもらえますか?

// cGo
package main

/*
#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h>
*/
import  "C"
//import "fmt"


func main() {
var t* C.sqlite3
C.sqlite3_open("test.db", t)

}

4

1 に答える 1

3

「未定義のシンボル」は、ビルド プロセスがコードをシステム上の sqlite ライブラリにリンクしていないことを意味します。

既存の go-sqlite ライブラリは、 SQLite のコード全体を #include した C ファイル(同じパッケージ内の lib/sqlite3.c) をパッケージ ディレクトリに配置することで、SQLite にリンクされます。また、いくつかのコンパイラ フラグ (CFLAGS) とsqlite3.goの C ラッパー関数も提供します。

このアプローチの便利な点は、SQLite が最終的にバイナリに直接リンクされることを意味するため、ユーザーはプログラムを実行する前に SQLite を個別にインストールする必要がないことです。純粋な Go ライブラリのみを使用するgc( とは対照的に) ツールチェーン上に構築されたプログラムは、デフォルトでこの方法であるため、そのようにするのは一種の「Go-y」です。gccgo

もう 1 つの方法は、宣言#cgo LDFLAGS: -lsqlite3の前にコードでcgo プラグマを使用することです。extern "C"その場合、ユーザーはバイナリを使用するために互換性のある sqlite3 ライブラリをインストールする必要がありますが、リポジトリにソースは必要なく、簡単かもしれません。このアプローチでは、パッケージをビルドしたい人は、システムに SQLite ヘッダーが必要であることに注意してください。たとえば、libsqlite3-devLinux ディストリビューションが提供するパッケージからです。

これが cgo とライブラリの統合の一般的なヘルプとして価値があることを願っています。go-sqlite3 または別の既存のラッパーを使用できる場合は、それを使用する方がうまくいく可能性が高いと思います。

于 2014-04-27T03:33:20.880 に答える