這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
如何在兩個不同的package中使用同樣的自訂資料類型?這裡主要針對包括在C標頭檔中結構體類型,如果只是在不同的go package中自訂資料類型,這個很好處理。但實際上處理的核心是一樣的,下面通過兩個例子來說明解決辦法。
測試常式目錄
├── include│ └── data.h└── src ├── common │ └── common.go └── main └── main.go
測試
data.h
#pragma once#include <stdio.h>struct Data { int a; char b;};
common.go
package common/*#include <stdio.h>#cgo CFLAGS : -I../../include#include "data.h"*/import "C"import ( "fmt")func Print(data *C.struct_Data) bool { fmt.Printf("data : %d %c\n", data.a, data.b) return true}
main.go
package main/*#include <stdio.h>#cgo CFLAGS : -I../../include#include "data.h"*/import "C"import ( "common")func main() { data := C.struct_Data{a: C.int(2), b: C.char('b')} common.Print(&data)}
$go run main.go
出現錯誤
.\main.go:19: cannot use &data (type *C.struct_Data) as type *common.C.struct_Data in argument to common.Print
錯誤解決方案
方法一
通過將data.h中的接頭體的成員變數名都改為大寫開頭的命名方式。然後在comm.go中type GData C.struct_Data
,再到main.go中直接使用common.GData
類型即可,不需要在main.go中再次包含data.h標頭檔。
package mainimport ( "common" "fmt")func main() { data := common.GData{A: 2, B: 'b'} fmt.Println(data) common.Print(&data)}
方法二
第一種方式我們可以自己通過修改data.h標頭檔達到目的,但是如果我們沒有許可權修改data.h的內容怎麼辦呢?即data.h中的結構體的成員變數的命名還是以小寫開頭。
首先需要知道的是,在不同的package中,include相同的標頭檔中資料類型,然後使用這個資料類型去傳遞到另一個package中的function中是會報上面的錯誤的。第二種方式就是利用set/get方式來操作。重新寫common.go和main.go:
common.go
package common/*#include <stdio.h>#cgo CFLAGS : -I../../include#include "data.h"*/import "C"import ( "fmt")type GData C.struct_Datafunc (data *GData) GDataSetA(a int) { data.a = C.int(a)}func (data *GData) GDataSetB(b byte) { data.b = C.char(b)}func Print(data *GData) bool { fmt.Printf("data : %d %c\n", data.a, data.b) return true}
main.go
package mainimport ( "common")func main() { data := common.GData{} data.GDataSetA(2) data.GDataSetB('b') common.Print(&data)}
這樣就統一了同一種資料類型,即在common包中GData類型。