golang調(diào)用windows平臺的dll庫的方法實現(xiàn)
1、dll 和 golang 的編譯架構(gòu)要一直,32位對應(yīng)32位,64位對應(yīng)64位,比如如果dll是32位的,而golang是64位的,可能會報錯%1 is not a valid Win32 application.
2、有時候存在類型轉(zhuǎn)換,需要開啟CGO,比如,如果dll中的函數(shù)返回一個字符串,那么返回值是一個字符串指針,還需要將返回值轉(zhuǎn)換成go字符串
import "C" str := C.GoString((*C.Char)(unsafe.Pointer(ret)))
3、傳入dll函數(shù)的參數(shù)被要求是 uintptr 類型,因此需要做轉(zhuǎn)換。
func IntPtr(n int) uintptr { return uintptr(n) } func Int2IntPtr(n int) uintptr { return uintptr(unsafe.Pointer(&n)) } func IntPtr2Ptr(n *int) uintptr { return uintptr(unsafe.Pointer(n)) } func BytePtr(s []byte) uintptr { return uintptr(unsafe.Pointer(&s[0])) } func StrPtr(s string) uintptr { return uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(s))) }
package main import ( "fmt" "syscall" ) // 設(shè)置console模式下標(biāo)準(zhǔn)輸出的字體前景色 var f = "SetConsoleTextAttribute" func main() { f1() f2() f3() f4() } func f1() { // A LazyDLL implements access to a single DLL. // It will delay the load of the DLL until the first // call to its Handle method or to one of its // LazyProc's Addr method. // // LazyDLL is subject to the same DLL preloading attacks as documented // on LoadDLL. // // Use LazyDLL in golang.org/x/sys/windows for a secure way to // load system DLLs. dll := syscall.NewLazyDLL("kernel32.dll") p := dll.NewProc(f) r1, r2, lastError := p.Call(uintptr(syscall.Stdout), uintptr(3)) fmt.Println(r1, r2, lastError) } func f2() { // LoadDLL loads the named DLL file into memory. // // If name is not an absolute path and is not a known system DLL used by // Go, Windows will search for the named DLL in many locations, causing // potential DLL preloading attacks. // // Use LazyDLL in golang.org/x/sys/windows for a secure way to // load system DLLs. dll, _ := syscall.LoadDLL("kernel32.dll") p, _ := dll.FindProc(f) r1, r2, lastError := p.Call(uintptr(syscall.Stdout), uintptr(4)) fmt.Println(r1, r2, lastError) } func f3() { // MustLoadDLL is like LoadDLL but panics if load operation fails. dll := syscall.MustLoadDLL("kernel32.dll") p := dll.MustFindProc(f) r1, r2, lastError := p.Call(uintptr(syscall.Stdout), uintptr(5)) fmt.Println(r1, r2, lastError) } func f4() { handle, _ := syscall.LoadLibrary("kernel32.dll") defer syscall.FreeLibrary(handle) p, _ := syscall.GetProcAddress(handle, f) r1, r2, errorNo := syscall.Syscall(p, 2, uintptr(syscall.Stdout), uintptr(6), 0) fmt.Println(r1, r2, errorNo) // 恢復(fù)到白色 syscall.Syscall(p, 2, uintptr(syscall.Stdout), uintptr(7), 0) }
到此這篇關(guān)于golang調(diào)用windows平臺的dll庫的方法實現(xiàn)的文章就介紹到這了,更多相關(guān)golang調(diào)用dll庫內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
golang中的io.ReadCloser與ioutil.NopCloser使用
這篇文章主要介紹了golang中的io.ReadCloser與ioutil.NopCloser使用方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-03-03GoZero中make后返回數(shù)據(jù)與原數(shù)據(jù)不對齊的幾種解決方案
在Go語言中,make是用來創(chuàng)建切片、映射(map)和通道(channel)的內(nèi)建函數(shù),但是,在使用 make 創(chuàng)建切片時,若不理解如何正確使用其返回值,可能會遇到數(shù)據(jù)對不上或結(jié)果不符合預(yù)期的情況,本文將分析在GoZero或其他基于Go的應(yīng)用中,使用make時可能導(dǎo)致的問題及解決方案2025-01-01淺談golang package中init方法的多處定義及運行順序問題
這篇文章主要介紹了淺談golang package中init方法的多處定義及運行順序問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-05-05淺析Golang切片截取功能與C++的vector區(qū)別
這篇文章主要介紹了Golang中切片的截取功能與C++中的vector有什么區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2022-10-10