亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何將 C.int 地址復制到cgo中的C.char中?

如何將 C.int 地址復制到cgo中的C.char中?

Go
絕地無雙 2022-08-24 15:38:08
使用cgo我正在調用c函數。我遇到了必須 C.int 地址復制到C.char[4]的情況。我可以在go中做到這一點嗎?代碼片段 C- 結構:struct data{    char    *a_add;     unsigned int length;}Go-Codefunc main() {     var d[3] C.data     var filedescriptor C.int     d[0].a_add = &filedescriptor      d[0].length = 4}問題是a_add是一個字符*。但是我需要傳遞int變量地址。c代碼是遺留代碼,我現在無法修復數據類型。其他C模塊使用它,并且它在C中工作并發出警告。在去的地方,這是錯誤。有沒有辦法將int變量的地址復制到cgo中的char*數組中。更新:我嘗試了d[0].a_add = (*C.char)(不安全。Pointer(&filedescriptor )),獲取錯誤:死機:運行時錯誤:cgo 參數具有指向 Go 指針的 Go 指針我錯過了什么?
查看完整描述

1 回答

?
叮當貓咪

TA貢獻1776條經驗 獲得超12個贊

您遇到的一個問題是,在對 C 代碼的調用中,您可能無法將指針傳遞給 Go 指針。該變量是一個 ,但是一個 Go 指針,因此您不能使用它(或者更確切地說,您不能在 a_add 字段中將其用作值)。filedescriptorC.int&filedescriptor


關于你的C代碼有很多我不清楚的地方,但你可以使用下面的代碼。請注意,對于您的特定情況,此代碼可能有些過頭了。它并不意味著特別高效或良好,在非常靈活的同時盡可能清晰 - 例如,它可以讀取和寫入打包的C結構。


package main


// #include <stdio.h>

// #include <stdlib.h>

// #include <string.h>

//

// struct data {

//     char *a_add;

//     unsigned int length;

// };

//

// void f(struct data *p) {

//    printf("p->a_add = %p, p->length = %u\n", p->a_add, p->length);

//    printf("p->a_add as an int: %d\n", *(int *)p->a_add);

//    *(int *)p->a_add = 0x12345678;

// }

import "C"


import (

        "fmt"

        "unsafe"

)


const cIntSize = C.sizeof_int


// Produce a Go int64 from a C int.  The caller passes the address

// of the C int.

func int64FromCInt(ci unsafe.Pointer) int64 {

        // Get a slice pointing to the bytes of the C int.

        sci := (*[cIntSize]byte)(ci)[:]

        switch {

        case cIntSize == unsafe.Sizeof(int64(0)):

                var gi int64

                sgi := (*[unsafe.Sizeof(gi)]byte)(unsafe.Pointer(&gi))[:]

                copy(sgi, sci)

                return gi

        case cIntSize == unsafe.Sizeof(int32(0)):

                var gi int32

                sgi := (*[unsafe.Sizeof(gi)]byte)(unsafe.Pointer(&gi))[:]

                copy(sgi, sci)

                return int64(gi)

        case cIntSize == unsafe.Sizeof(int(0)):

                var gi int

                sgi := (*[unsafe.Sizeof(gi)]byte)(unsafe.Pointer(&gi))[:]

                copy(sgi, sci)

                return int64(gi)

        default:

                panic("no Go integer size matches C integer size")

        }

}


// Write C int (via an unsafe.Pointer) from Go int.  The caller

// passes the address of the C int.

func writeCIntFromInt(gi int, ci unsafe.Pointer) {

        // Get a slices covering the bytes of the C int.

        sci := (*[cIntSize]byte)(ci)[:]

        switch {

        case cIntSize == unsafe.Sizeof(gi):

                sgi := (*[unsafe.Sizeof(gi)]byte)(unsafe.Pointer(&gi))[:]

                copy(sci, sgi)

        case cIntSize == unsafe.Sizeof(int64(0)):

                // Copy value to int64 for copying purposes.

                // Since int64 holds all int values, this always works.

                gi2 := int64(gi)

                sgi := (*[unsafe.Sizeof(gi)]byte)(unsafe.Pointer(&gi2))[:]

                copy(sci, sgi)

        case cIntSize == unsafe.Sizeof(int32(0)):

                // Copy value to int32 for copying purposes.

                // Panic if we destroy the value via truncation.

                gi2 := int32(gi)

                if int(gi2) != gi {

                        panic(fmt.Sprintf("unable to send Go value %x to C: size of Go int=%d, size of C int=%d", gi, unsafe.Sizeof(gi), cIntSize))

                }

                sgi := (*[unsafe.Sizeof(gi)]byte)(unsafe.Pointer(&gi2))[:]

                copy(sci, sgi)

        default:

                panic("no Go integer size matches C integer size")

        }

}


func main() {

        b := C.malloc(cIntSize)

        defer C.free(b)

        writeCIntFromInt(32767, b)

        d := C.struct_data{a_add: (*C.char)(b), length: cIntSize}

        fmt.Println("calling C.f(d)")

        C.f(&d)

        result := int64FromCInt(unsafe.Pointer(d.a_add))

        fmt.Printf("result = %#x\n", result)

}



查看完整回答
反對 回復 2022-08-24
  • 1 回答
  • 0 關注
  • 130 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號