我有問題時使用cgo與c結構數組。cgo使用c結構數組並在去分配值
我的如下程序:
我在C結構和包含一個指向一個C結構陣列。
在C中,我提供了一個初始化函數(取兩個參數:指向變量的指針,變量內部數組的長度)給malloc變量的內存。
然後在go中,我將值賦給這個變量,並賦值給變量中的數組。然後,我會調用另一個C函數來使用這個變量。
C函數處理它之後。再次選取變量並返回其他Go功能。
當我編碼像這樣,我去了一個數組。鍵入* C.struct不支持索引。
我的代碼如下。
C:
test.h
typedef struct
{
int profileCnt;
_profile *profile; //pointer to profile array
}_profiles;
// variable using in Go
typedef struct
{
int profileId;
_name userName;
char *dateOfBirth;
int stateFipsId;
}_profile;
typedef struct
{
char first[32];
char last[32];
} _name;
void initializeProfiles(_profiles *profiles, int profileCount, bool create);
int doSomething _In_C(_profiles *profiles, int log);
test.c的
void initializeProfiles(_profiles *profiles, int profileCount, bool create)
{
profiles->profileCnt = profileCount;
// initialize profiles struct & profile[] Array
if (profileCount > 0)
{
if (create == true)
profiles->profile = malloc(profileCount * sizeof *profiles->profile + 1); // allocate memory for profiles[numProfiles]
for (int i = 0; i < profiles->profileCnt; i++)
initializeProfile(&profiles->profile[i], create);
if (create == false)
{
free(profiles->profile);
profiles->profileCnt = 0;
}
}
else
profiles->profile = NULL;
}
void initializeProfile(_profile *profile, bool create)
{
if (create == true)
{
profile->dateOfBirth = NULL;
}
profile->profileId = 0;
memset(profile->userName.first, '\0', sizeof(profile->userName.first));
memset(profile->userName.last, '\0', sizeof(profile->userName.last));
if (create == false)
{
if (profile->dateOfBirth != NULL)
free(profile->dateOfBirth);
}
}
int doSomething _In_C(_profiles *profiles, int log)
{
/* ===========================================
*/ ==== did something to that variable============================
if (errStatus.code == _SUCCESS)
return(_SUCCESS);
else
return(FAILURE);
}
我的GO代碼
package main
//#cgo CFLAGS: -std=c99 -ggdb3 -O0 -Wall
//#cgo CFLAGS: -I../../include/common
//#cgo LDFLAGS: -L string.h
//#cgo LDFLAGS: -lstdc++ -lpthread -lm -lc -lssl -lcrypto
//#include <stdio.h>
//#include <stdlib.h>
//#include "test.h"
import "C"
//import "unsafe"
func Test() {
log := 1 // sets logging level
numProfiles := 3
var profiles C._profiles
C.initializeProfiles(&profiles, C.int(numProfiles), C.bool(true))
profiles.profile[0].profileId = C.int(2)
profiles.profile[0].stateFipsId = C.int(1)
profiles.profile[0].userName.first = C.CString("test")
profiles.profile[0].userName.last = C.CString("test")
C.dosomething_In_C(&profiles,C.int(3))
C.initializeProfiles(&profiles, C.int(numProfiles), C.bool(false))
fmt.Println(int("get c variable and return")
}
當我編譯在這樣 profiles.profi勒[0] = .profileId C.int(2)
我得到錯誤消息: 無效操作:profiles.profile [0](類型* C.struct ___ 6不支持索引)
所以,我嘗試其他解決方案傳遞c結構數組形式c去。這樣
profile.profikes = (*[1 << 30]C._profile)(unsafe.Pointer(&profiles.profile))[:numProfiles:numProfiles]
但是,像不能用得到錯誤(* [1073741824] C.struct ___ 6)(unsafe.Pointer(& profiles.profile)):numProfiles:numProfiles(鍵入[] C.struct ___ 6)鍵入* C.struct ___ 6賦值
我恐怕會創建另一塊內存,當我在dosomething_In_C函數中調用時,它無法獲取數據。
有人知道如何解決這個問題嗎?
謝謝你
謝謝JimB。其實,我需要參考相同的記憶。因爲初始化和賦值後我需要傳遞給另一個C函數作爲參數。一旦我使用具有固定長度數組結構的C結構,它就支持索引。我可以直接賦值,如profies.profile [0] .profileId = C.int(2)。但是,何時可以動態長度數組它不能。 –
@weiZhang:我不明白。我說這個_does_引用了相同的內存,並且沒有什麼能阻止你將指針傳遞迴C函數。這只是讓你用Go的索引符號訪問數組值。 – JimB
謝謝,我會嘗試再次調試。 –