繁体   English   中英

cgo使用c struct数组并在go中赋值

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM