我想使用 Go 庫,并在 C 中進(jìn)行一些調(diào)整。我制作了 GoAdder Go 函數(shù),它有 3 個參數(shù) int x、y 和函數(shù)類型 f。GoAdder 函數(shù)將調(diào)用 f 參數(shù)。加法器package mainimport "fmt"import "C" //export Ftesttype Ftest func(C.int);//export GoAdderfunc GoAdder(x, y int, f Ftest) int { fmt.Printf("Go says: adding %v and %v\n", x, y) f(10); return x + y}func main() {} // Required but ignored我在上面將 go 包構(gòu)建為名為 libadder.a 的靜態(tài)庫,如下所示:go build -buildmode=c-archive -o libadder.a adder.go然后我寫了下面的C++代碼。主程序#include <stdio.h>#include "adder/libadder.h"void a( GoInt a ){ printf("Hello %d", a);}int main() { printf("C says: about to call Go...\n"); int total = GoAdder(1, 7, &a); printf("C says: Go calculated our total as %i\n", total); return 0;}我已經(jīng)整理了這樣的來源:gcc -pthread -o static_go_lib main.c adder/libadder.a執(zhí)行上面的代碼時出現(xiàn)錯誤unexpected fault address 0x0fatal error: fault[signal SIGSEGV: segmentation violation code=0x80 addr=0x0 pc=0x563c99b74244]goroutine 17 [running, locked to thread]:...如何在go函數(shù)GoAdder中獲取正確的C函數(shù)地址a?我引用了https://github.com/draffensperger/go-interlang/tree/master/c_to_go/static_go_lib
1 回答

30秒到達(dá)戰(zhàn)場
TA貢獻(xiàn)1828條經(jīng)驗 獲得超6個贊
C函數(shù)只是跳轉(zhuǎn)指針,而golang的回調(diào)是復(fù)雜的結(jié)構(gòu)體,并且無法轉(zhuǎn)換它們。只有一種(安全)方法來調(diào)用 C 函數(shù)指針:1)在某處聲明:
//go:linkname cgocall runtime.cgocall
//go:nosplit
func cgocall(fn, arg unsafe.Pointer /* may be uintptr */) int32
2)另外,要保證類型安全:
func GoAdder(x, y C.int, f unsafe.Pointer /* don't sure if this available, mb C.uintptr_t */) C.int
3)C函數(shù)應(yīng)該以指針(指向任何東西)作為參數(shù)
void a(GoInt *a)
(我會使用本機(jī)類型)
4)
ten := 10
cgocall(f, unsafe.Pointer(&ten))
(如果你想傳遞幾個參數(shù),它應(yīng)該是結(jié)構(gòu)體)
- 1 回答
- 0 關(guān)注
- 118 瀏覽
添加回答
舉報
0/150
提交
取消