Go與C數(shù)據(jù)交互:高效CGO數(shù)組處理詳解
本文將深入探討go語言中使用CGO處理c語言數(shù)組的技巧,并解決Go和C數(shù)據(jù)交互中常見的難題,特別是如何正確獲取C數(shù)組數(shù)據(jù)以及C字符串到Go字符串的轉(zhuǎn)換。
直接訪問C結(jié)構(gòu)體數(shù)組時,常常會遇到問題。例如,如果C結(jié)構(gòu)體成員是字符數(shù)組,Go端直接訪問只能得到第一個元素的地址,無法獲取完整數(shù)據(jù)。打印結(jié)果也只會顯示C字符串的內(nèi)存地址,而非實際字符串內(nèi)容。
為了解決這些問題,我們需要優(yōu)化C代碼的結(jié)構(gòu)體定義和數(shù)據(jù)訪問方式。改進后的C代碼將user結(jié)構(gòu)體的name成員修改為char *,即指向字符串的指針,允許動態(tài)內(nèi)存分配和字符串存儲。同時,引入users結(jié)構(gòu)體來管理user結(jié)構(gòu)體數(shù)組,方便數(shù)據(jù)訪問。
立即學習“go語言免費學習筆記(深入)”;
改進后的C代碼:
#include <stdint.h> #include <stdlib.h> #include <string.h> typedef struct user { char *name; int uid; } user; typedef struct users { user items[3]; } users; static struct users *getusers() { static struct users *p; static struct users users; users.items[0].name = "admin1"; users.items[0].uid = 1; users.items[1].name = "admin2"; users.items[1].uid = 2; users.items[2].name = "admin3"; users.items[2].uid = 3; p = &users; return p; }
相應的Go代碼也需要調(diào)整,使用循環(huán)遍歷users結(jié)構(gòu)體中的user數(shù)組,并利用C.GoString函數(shù)將C字符串轉(zhuǎn)換為Go字符串。
改進后的Go代碼:
package main /* #include <stdint.h> #include <stdlib.h> #include <string.h> typedef struct User { char *name; int uid; } User; typedef struct Users { User items[3]; } Users; static struct Users *getUsers() { static struct Users *p; static struct Users users; users.items[0].name = "admin1"; users.items[0].uid = 1; users.items[1].name = "admin2"; users.items[1].uid = 2; users.items[2].name = "admin3"; users.items[2].uid = 3; p = &users; return p; } */ import "C" import ( "fmt" ) func main() { ptr := C.getUsers() for k, v := range ptr.items { fmt.Println(k, C.GoString((*C.char)(v.name))) } }
通過這些改進,我們有效解決了數(shù)組數(shù)據(jù)訪問不完整和C字符串轉(zhuǎn)換的問題,實現(xiàn)了Go和C代碼之間的高效數(shù)據(jù)交互。