第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

從 C 訪問 Go 的數(shù)組數(shù)組

從 C 訪問 Go 的數(shù)組數(shù)組

Go
夢(mèng)里花落0921 2023-07-10 10:07:48
澄清:似乎沒有將 GO 映射作為多維數(shù)組發(fā)送到 C 函數(shù)的記錄示例。這個(gè)問題旨在為從 GO 發(fā)送數(shù)據(jù)集合到 C 的任何人找到一個(gè)通用的解決方案。問題: 我在 Go 中有一個(gè) map[string]string,我希望在 C++ 中迭代這個(gè)鍵/值對(duì)。在 GO 中,我有以下內(nèi)容來創(chuàng)建多維數(shù)組    var argv = make([][]*C.char, len(keypairs))    count := 0    for key, val := range keypairs {        var argv2 = make([]*C.char, 2)        csKey := C.CString(key)        csVal := C.CString(val)        argv2[0] = csKey        argv2[1] = csVal        argv[count] = argv2        count++        C.free(unsafe.Pointer(csKey))        C.free(unsafe.Pointer(csVal))    }    C.writeKeyValuePairs(&argv[0])然后在 C++ 中我有:bool writeKeyValuePairs(char * pairs[][2]) {     ...}結(jié)果是: cannot use _cgo1 (type *[]*_Ctype_char) as type *[2]*_Ctype_char in argument更新@kostix: 這是現(xiàn)在的位置:    var argv = make([][2]*C.char, len(tags))    i := 0    for key, val := range tags {        var argv2 = new([2]*C.char)        argv2[0], argv2[1] = C.CString(key), C.CString(val)        argv[i] = argv2        i++    }    C.writeKeyValuePairs(&argv[0])錯(cuò)誤是: Cannot use 'argv2' (type *[2]*C.char) as type [2]*C.char
查看完整描述

2 回答

?
郎朗坤

TA貢獻(xiàn)1921條經(jīng)驗(yàn) 獲得超9個(gè)贊

在 Go 中,[]T它并不像你想象的那樣:它不是一個(gè)數(shù)組,而是一個(gè)切片。

切片由struct三個(gè)字段組成:length int,capacity int以及指向基礎(chǔ)(支持)數(shù)組的第一個(gè)元素的指針。

相反,在 C 和 C++ 中,a直接T[]是指向內(nèi)存塊的指針(其迭代恰好以字節(jié)塊的形式完成)。sizeof(T)

因此你char *pairs[][2]

  • 指向類型為兩個(gè)元素的內(nèi)存塊的指針char*[],

  • 其中每個(gè)元素都是指向另一個(gè)包含未知數(shù)量的類型元素的數(shù)組的指針char*

…你的 Go[][]*C.char是一個(gè)切片的切片(即struct- 類型的切片頭,而不是指針)。

你可能需要這樣的東西:

    var argv = make([][2]*C.char, len(keypairs))

    i := 0

    for key, val := range keypairs {

        var argv2 = new([2]*C.char)

        argv2[0], argv2[1] := C.CString(key), C.CString(val)

        argv[i] = argv2

        i++

    }

    C.writeKeyValuePairs(&argv[0])

這里我們分配一個(gè)數(shù)組切片(長(zhǎng)度為 2)。在調(diào)用 C 端時(shí),您可以正確獲取封閉數(shù)組的第一個(gè)元素的地址,因此在頂層有一個(gè)切片就可以了。


這段代碼的問題是,您沒有傳遞數(shù)據(jù)的長(zhǎng)度argv,writeKeyValuePairs也沒有在該數(shù)組的末尾使用哨兵值,但我希望您剛剛從示例中刪除了該位。


C.CString我也無法理解為什么你立即釋放分配的內(nèi)存。手冊(cè)說:


// Go string to C string

// The C string is allocated in the C heap using malloc.

// It is the caller's responsibility to arrange for it to be

// freed, such as by calling C.free (be sure to include stdlib.h

// if C.free is needed).

func C.CString(string) *C.char

因此,在指向鍵/值對(duì)的指針被分配給相應(yīng)的數(shù)組條目對(duì)之后,您似乎立即釋放了鍵/值對(duì)的內(nèi)存塊。我懷疑這是一個(gè)錯(cuò)誤:釋放必須在 C 函數(shù)完成執(zhí)行后進(jìn)行。


查看完整回答
反對(duì) 回復(fù) 2023-07-10
?
慕運(yùn)維8079593

TA貢獻(xiàn)1876條經(jīng)驗(yàn) 獲得超5個(gè)贊

我在 Go 中有一個(gè) map[string]string,我希望在 C++ 中迭代這個(gè)鍵/值對(duì)。


用你的例子,


package main


/*

#include <stdlib.h>

#include <stdio.h>

#include <stdbool.h>


bool writeKeyValuePairs(char *pairs[][2], size_t size) {

    for (size_t i = 0; i < size; i++ ) {

        if (fprintf(stdout, "%s: %s\n", pairs[i][0], pairs[i][1]) < 0) {

            return false;

        }

    }

    return true;

}

*/

import "C"


import (

    "fmt"

    "os"

    "unsafe"

)


func allocCPairs(m map[string]string) (*[2]*C.char, C.size_t) {

    kv := make([][2]*C.char, 0, len(m)+1)

    for k, v := range m {

        kv = append(kv, [2]*C.char{0: C.CString(k), 1: C.CString(v)})

    }

    return &kv[:cap(kv)][0], C.size_t(len(kv))

}


func freeCPairs(cPairs *[2]*C.char, size C.size_t) {

    gPairs := (*[1 << 30][2]*C.char)(unsafe.Pointer(cPairs))[:size]

    for _, pair := range gPairs {

        for _, p := range pair {

            C.free(unsafe.Pointer(p))

        }

    }

}


func writeKeyValuePairs(m map[string]string) error {

    cPairs, size := allocCPairs(m)

    defer freeCPairs(cPairs, size)


    rv := C.writeKeyValuePairs(cPairs, size)

    if !rv {

        return fmt.Errorf("writeKeyValuePairs: write error")

    }

    return nil

}


func main() {

    m := map[string]string{

        "K1": "V1",

        "K2": "V2",

        // ...

        "Kn": "Vn",

    }

    fmt.Println(m)


    err := writeKeyValuePairs(m)

    if err != nil {

        fmt.Fprintln(os.Stderr, err)

        return

    }

}

輸出:


map[K1:V1 K2:V2 Kn:Vn]

K1: V1

K2: V2

Kn: Vn


查看完整回答
反對(duì) 回復(fù) 2023-07-10
  • 2 回答
  • 0 關(guān)注
  • 159 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)