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

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

golang從dll獲取char*作為返回值

golang從dll獲取char*作為返回值

Go
慕運(yùn)維8079593 2023-07-26 15:38:22
我正在使用 golang 調(diào)用 Dll 函數(shù),例如char* fn(),該 dll 不是我自己編寫的,我無(wú)法更改它。這是我的代碼:package mainimport (    "fmt"    "syscall"    "unsafe")func main() {    dll := syscall.MustLoadDLL("my.dll")    fn := dll.MustFindProc("fn")    r, _, _ := fn.Call()    p := (*byte)(unsafe.Pointer(r))    // define a slice to fill with the p string    data := make([]byte, 0)    // loop until find '\0'    for *p != 0 {        data = append(data, *p)        // append 1 byte        r += unsafe.Sizeof(byte(0))    // move r to next byte        p = (*byte)(unsafe.Pointer(r)) // get the byte value    }    name := string(data) // convert to Golang string    fmt.Println(name)}我有一些疑問(wèn):有更好的方法嗎?像這樣的 dll 函數(shù)有數(shù)百個(gè),我必須為所有函數(shù)編寫循環(huán)。對(duì)于像100k+字節(jié)這樣的非常長(zhǎng)的字符串,會(huì)append()導(dǎo)致性能問(wèn)題嗎?解決了。原因unsafe.Pointer(r)linter govet顯示警告possible misuse of unsafe.Pointer,但代碼運(yùn)行良好,如何避免此警告?解決方案:可以通過(guò)-unsafeptr=false在govet命令行中添加來(lái)解決,對(duì)于vim-ale,添加let g:ale_go_govet_options = '-unsafeptr=false'。
查看完整描述

2 回答

?
慕村9548890

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

將 uintptr 轉(zhuǎn)換為上指針是非法的。您必須閱讀規(guī)則:?https://golang.org/pkg/unsafe/#Pointer

但有一種 hacky 方法,不應(yīng)該產(chǎn)生警告:

//go:linkname gostringn? ? ?runtime.gostringn

func gostringn(p uintptr, l int) string


//go:linkname findnull? ? ?runtime.findnull

//go:nosplit

func findnull(s uintptr) int


// ....


name := gostringn(r, findnull(r))

函數(shù)接受指針,但我們從運(yùn)行時(shí)將它們鏈接為 uintptr,因?yàn)樗鼈兙哂邢嗤?sizeof。


理論上可能有效。但也被人皺眉。


回到你的代碼,你可以用一行代碼來(lái)完成:


name := C.GoString((*C.char)(unsafe.Pointer(r)))


查看完整回答
反對(duì) 回復(fù) 2023-07-26
?
蕭十郎

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

我通過(guò)跟蹤go源碼得到了以下解決方案os.Args,但是我是基于go1.17。如果您是其他版本,可以閱讀源碼來(lái)解決。


func UintPtrToString(r uintptr) string {

    p := (*uint16)(unsafe.Pointer(r))

    if p == nil {

        return ""

    }


    n, end, add := 0, unsafe.Pointer(p), unsafe.Sizeof(*p)

    for *(*uint16)(end) != 0 {

        end = unsafe.Add(end, add)

        n++

    }

    return string(utf16.Decode(unsafe.Slice(p, n)))

}


查看完整回答
反對(duì) 回復(fù) 2023-07-26
  • 2 回答
  • 0 關(guān)注
  • 328 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號(hào)

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