[英]cgo using c struct array and assign value in go
使用带c struct数组的cgo时遇到问题。
我的计划如下:
我在c中有struct并包含一个指向ac struct array的指针。
在C中,我提供了一个初始化函数(取两个参数:指向变量的指针,变量内部数组的长度)来malloc变量的内存。
然后在go中,我将值赋给此变量并将值赋给变量中的数组。 在go中,我调用另一个C函数来使用这个变量。
在C函数处理之后。 再次获取变量并返回其他Go功能。
当我像这样编码时,我就像一个数组。 type * 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.profile [0] .profileId = C.int(2)编译时
我收到错误消息:无效操作:profiles.profile [0](类型* C.struct ___ 6不支持索引)
所以,我尝试另一种解决方案。 传递c struct数组c转到go。 像这样
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函数时,它无法获取数据。
有谁知道如何解决这个问题?
谢谢
您不能索引C数组,也不能将Go切片分配给C结构,但是您不需要,因为新切片引用了相同的内存区域。
p := (*[1 << 30]C._profile)(unsafe.Pointer(profiles.profile))[:numProfiles:numProfiles]
p[0].profileId = C.int(2)
p[0].stateFipsId = C.int(1)
p[0].userName.first = C.CString("test")
p[0].userName.last = C.CString("test")
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.