Golang呼び出しsoファイルの例
6768 ワード
ダイナミックライブラリのテスト
test_so.h int test_so_func(int a,int b);
test_so.c #include "test_so.h"
int test_so_func(int a,int b)
{
return a*b;
}
soを生成するgcc -shared ./test_so.c -o test_so.so
soファイルをGoプロジェクトディレクトリにコピー
Goプロジェクトディレクトリ
load_so.h int do_test_so_func(int a,int b);
load_so.c #include "load_so.h"
#include
int do_test_so_func(int a,int b)
{
void* handle;
typedef int (*FPTR)(int,int);
handle = dlopen("./test_so.so", 1);
FPTR fptr = (FPTR)dlsym(handle, "test_so_func");
int result = (*fptr)(a,b);
return result;
}
test.go package main
/*
#include "load_so.h"
#cgo LDFLAGS: -ldl
*/
import "C"
import "fmt"
func main() {
fmt.Println("20*30=", C.do_test_so_func(20, 30))
}
Goプロジェクトディレクトリは$GOPATH/src/
ディレクトリの下に置くのも正常です.├── bin
├── pkg
└── src
└── test
├── go.mod
├── load_so.c
├── load_so.h
├── test
├── test.go
├── test_so.c
├── test_so.h
└── test_so.so
testディレクトリはGoプロジェクトで、上記で作成したすべてのソースファイルが含まれています.$GOPATH/src/test/
でgo build
を直接使用してtest
バイナリファイルをコンパイルして生成します.ここでは、実行パスに注意する必要があります.
うんてん$ ./test
20*30= 600
に質問
1、/**/注釈のコード次の行は必ずimport“C”で、中間に空白の行があってはいけません2、import“C”は単独で1行でなければならなくて、他のライブラリと一緒に導入することができません3、誰かがコンパイルする時に間違いを報告します:$ go build
# command-line-arguments
/tmp/go-build489385520/b001/_x002.o: In function `_cgo_49a6b71449ae_Cfunc_do_test_so_func':
/tmp/go-build/cgo-gcc-prolog:54: undefined reference to `do_test_so_func'
collect2: error: ld returned 1 exit status
これは主に実行ディレクトリの問題で、必ず$GOPATH/src/ /
ディレクトリの下で、go build
で実行し、go build
の後ろにファイル名がないでください.またはgo run .
で実行したり、go run test
で実行したりして、testはプロジェクト名です.go run test.go
は使えません.
4、この間違いを報告する人もいます.$ go build
# test
/tmp/go-build043875804/b001/_x003.o: In function `do_test_so_func':
./load_so.c:17: undefined reference to `dlopen'
./load_so.c:18: undefined reference to `dlsym'
collect2: error: ld returned 1 exit status
test.goファイルのcgo LDFLAGS: -ldl
行は削除しないでください.
int test_so_func(int a,int b);
#include "test_so.h"
int test_so_func(int a,int b)
{
return a*b;
}
gcc -shared ./test_so.c -o test_so.so
load_so.h
int do_test_so_func(int a,int b);
load_so.c
#include "load_so.h"
#include
int do_test_so_func(int a,int b)
{
void* handle;
typedef int (*FPTR)(int,int);
handle = dlopen("./test_so.so", 1);
FPTR fptr = (FPTR)dlsym(handle, "test_so_func");
int result = (*fptr)(a,b);
return result;
}
test.go
package main
/*
#include "load_so.h"
#cgo LDFLAGS: -ldl
*/
import "C"
import "fmt"
func main() {
fmt.Println("20*30=", C.do_test_so_func(20, 30))
}
Goプロジェクトディレクトリは
$GOPATH/src/
ディレクトリの下に置くのも正常です.├── bin
├── pkg
└── src
└── test
├── go.mod
├── load_so.c
├── load_so.h
├── test
├── test.go
├── test_so.c
├── test_so.h
└── test_so.so
testディレクトリはGoプロジェクトで、上記で作成したすべてのソースファイルが含まれています.
$GOPATH/src/test/
でgo build
を直接使用してtest
バイナリファイルをコンパイルして生成します.ここでは、実行パスに注意する必要があります.うんてん
$ ./test
20*30= 600
に質問
1、/**/注釈のコード次の行は必ずimport“C”で、中間に空白の行があってはいけません2、import“C”は単独で1行でなければならなくて、他のライブラリと一緒に導入することができません3、誰かがコンパイルする時に間違いを報告します:$ go build
# command-line-arguments
/tmp/go-build489385520/b001/_x002.o: In function `_cgo_49a6b71449ae_Cfunc_do_test_so_func':
/tmp/go-build/cgo-gcc-prolog:54: undefined reference to `do_test_so_func'
collect2: error: ld returned 1 exit status
これは主に実行ディレクトリの問題で、必ず$GOPATH/src/ /
ディレクトリの下で、go build
で実行し、go build
の後ろにファイル名がないでください.またはgo run .
で実行したり、go run test
で実行したりして、testはプロジェクト名です.go run test.go
は使えません.
4、この間違いを報告する人もいます.$ go build
# test
/tmp/go-build043875804/b001/_x003.o: In function `do_test_so_func':
./load_so.c:17: undefined reference to `dlopen'
./load_so.c:18: undefined reference to `dlsym'
collect2: error: ld returned 1 exit status
test.goファイルのcgo LDFLAGS: -ldl
行は削除しないでください.
$ go build
# command-line-arguments
/tmp/go-build489385520/b001/_x002.o: In function `_cgo_49a6b71449ae_Cfunc_do_test_so_func':
/tmp/go-build/cgo-gcc-prolog:54: undefined reference to `do_test_so_func'
collect2: error: ld returned 1 exit status
$ go build
# test
/tmp/go-build043875804/b001/_x003.o: In function `do_test_so_func':
./load_so.c:17: undefined reference to `dlopen'
./load_so.c:18: undefined reference to `dlsym'
collect2: error: ld returned 1 exit status