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

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

將字符串傳遞給 Syscall(uintptr)

將字符串傳遞給 Syscall(uintptr)

Go
qq_花開花謝_0 2023-03-21 16:54:35
我需要將字符串作為參數(shù)傳遞給 golang 中的 C DLL,我想得到這樣的東西:  proc, e = syscall.GetProcAddress(h, "JLINKARM_ExecCommand") //One of the functions    vals := []string{"device = STM32F429ZI"}    start := uintptr(unsafe.Pointer(&vals[0]))    asd, _, _ = syscall.Syscall6(uintptr(proc), 3, start, 0, 0, 0, 0, 0) 但它不起作用。系統(tǒng)調(diào)用將 uintptr 作為參數(shù)。我不能使用 C 包,因為它不能在 Windows 上構(gòu)建。在 C 中,它的工作方式如下:strcpy(acIn, "device = STM32F407IE");JLINKARM_ExecCommand(acIn, &acOut[0], sizeof(acOut));那么 C DLL 是否有機會獲取字符串參數(shù)并正確使用它?
查看完整描述

2 回答

?
翻過高山走不出你

TA貢獻1875條經(jīng)驗 獲得超3個贊

要將字符串傳遞給系統(tǒng)調(diào)用,您需要傳遞指向字符串第一個字符的指針。第一個問題是您的 DLL 函數(shù)需要什么字符串編碼。Go 字符串被編碼為 UTF-8 unicode,因此如果您的 C 函數(shù)需要其他內(nèi)容,您必須先轉(zhuǎn)換它們。以下是一些常見的情況:


1)ASCII字符串

假設(shè)您的 C 函數(shù)需要一個以零結(jié)尾的 ASCII 字符串,那么您可以執(zhí)行以下操作:


s := "some string"

b := append([]byte(s), 0)

syscall.Syscall(uintptr(proc), 1, uintptr(unsafe.Pointer(&b[0])), 0, 0)

首先將您的字符串轉(zhuǎn)換為字節(jié)數(shù)組,并在末尾添加 C 期望的零。然后將指針傳遞給第一個字節(jié)字符。


為了安全起見,您還應(yīng)該確保您實際上只傳入有效的 ASCII 字符串,沒有無效字符。通常只有 [0..127] 范圍內(nèi)的字符對通用 ASCII 有效。其余取決于當前代碼頁。


2) Windows 上的 UTF-16

如果您調(diào)用 Windows DLL,您通常希望使用該函數(shù)的 UTF-16 版本,例如SendMessageW,因此需要將您的字符串轉(zhuǎn)換為 UTF-16。幸運的是,在 Windows 下有一個包裝函數(shù),因此您只需執(zhí)行以下操作:


s := "some string"

s16, err := syscall.UTF16PtrFromString(s)

if err == nil {

    syscall.Syscall(uintptr(proc), 1, uintptr(unsafe.Pointer(s16)), 0, 0)

}

這將轉(zhuǎn)換為 UTF-16 并在末尾為您附加預(yù)期的零。


查看完整回答
反對 回復(fù) 2023-03-21
?
青春有我

TA貢獻1784條經(jīng)驗 獲得超8個贊

處理這個問題的一個好方法是使用mkwinsyscall工具。你可以像這樣創(chuàng)建一個 Go 文件:

package main

//go:generate mkwinsyscall -output zmsi.go msi.go

//sys MsiInstallProduct(path string, command string) (e error) = msi.MsiInstallProductW

然后運行g(shù)o generate,你會得到一個這樣的結(jié)果文件(為簡潔起見刪除了一些部分):


func MsiInstallProduct(path string, command string) (e error) {

    var _p0 *uint16

    _p0, e = syscall.UTF16PtrFromString(path)

    if e != nil {

        return

    }

    var _p1 *uint16

    _p1, e = syscall.UTF16PtrFromString(command)

    if e != nil {

        return

    }

    return _MsiInstallProduct(_p0, _p1)

}


func _MsiInstallProduct(path *uint16, command *uint16) (e error) {

    r0, _, _ := syscall.Syscall(procMsiInstallProductW.Addr(), 2, uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(command)), 0)

    if r0 != 0 {

        e = syscall.Errno(r0)

    }

    return

}

如您所見,它會自動處理字符串轉(zhuǎn)換、系統(tǒng)調(diào)用代碼,甚至錯誤處理。


查看完整回答
反對 回復(fù) 2023-03-21
  • 2 回答
  • 0 關(guān)注
  • 249 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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