登录
首页 >  Golang >  Go问答

在 Go 中循环遍历 C 数组数据

来源:stackoverflow

时间:2024-03-25 23:54:28 316浏览 收藏

在 Go 语言中循环遍历 C 数组数据时,如果 C 函数返回一个数组,需要将数组转换为 Go 中的 slice 类型才能进行遍历。文章中遇到的问题是 pkcs11_enumerate_keys 函数返回一个 PKCS11_KEY 数组,而 Go 中直接遍历数组时只能访问第一个元素。通过将数组转换为 slice,使用 unsafe.Slice 函数,就可以对数组中的所有元素进行遍历。

问题内容

package main

//#cgo ldflags: -ldl -lp11
//#include 
//#include 
import "c"

import (
        "log"
        "unsafe"
        "fmt"
        //"runtime"
        //"reflect"
)

func main(){
        var ctx *c.pkcs11_ctx
        ctx = c.pkcs11_ctx_new()
        //log.println(ctx)

        cmodulepath := c.cstring("/home/procondutor/libaetpkss.so.3.0.3930")
        defer c.free(unsafe.pointer(cmodulepath))

        rc := c.pkcs11_ctx_load(ctx, cmodulepath)
        if rc < 0 {
                log.println("1 erro rc menor que 0")
                return
        }

        var slots, slot *c.pkcs11_slot
        var keys *c.pkcs11_key
        var nslots, nkeys uint
        p := unsafe.pointer(&nslots)
        n := unsafe.pointer(&nkeys)

        //log.println(nkeys)
        rc = c.pkcs11_enumerate_slots(ctx, &slots, (*c.uint)(p))
        if rc < 0 {
                log.println("2 erro rc menor que 0")
                return
        }

        slot = c.pkcs11_find_token(ctx, slots, c.uint(nslots));

        s := c.gostring(slot.manufacturer)
        fmt.printf("%+v\n", s)

        cpin := c.cstring("2903")
        defer c.free(unsafe.pointer(cpin))

        rc = c.pkcs11_login(slot, 0, cpin);
        if rc < 0 {
                log.println("3 erro rc menor que 0")
                return
        }

        rc = c.pkcs11_enumerate_keys(slot.token, &keys, (*c.uint)(n));
        if rc < 0 {
                log.println("4 erro rc menor que 0")
                return
        }

我的问题出在 pkcs11_enumerate_keys 函数中,在 c 中,该函数根据以下代码返回一个列表:

static void list_keys(const char *title, const PKCS11_KEY *keys,
        const unsigned int nkeys) {
    unsigned int i;

    printf("\n%s:\n", title);
    for (i = 0; i < nkeys; i++)
        printf(" * %s key: %s\n",
            keys[i].isPrivate ? "Private" : "Public", keys[i].label);
}

但在 go 中它只返回第一个对象。 如果我尝试在 go 中进行迭代,则会收到以下错误: 无效操作:无法索引键(*_ctype_struct_pkcs11_key_st 类型的变量)


正确答案


我终于用下面的代码得到了它:

list_keys := unsafe.Slice(keys, nkeys)
        for i := 0; i < int(nkeys); i++ {
                z:= C.GoString(slice[i].label)
                fmt.Println(z)
        }

今天带大家了解了的相关知识,希望对你有所帮助;关于Golang的技术知识我们会一点点深入介绍,欢迎大家关注golang学习网公众号,一起学习编程~

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>