golang 交叉編譯C++ dll配置文件的實(shí)現(xiàn)
調(diào)用c++ 報(bào)%1 is not a valid Win32 application
開(kāi)發(fā)環(huán)境:
win64位
C++ dll 為32位
首先遇到的坑就是環(huán)境的配置,調(diào)用了一個(gè)之前C++寫的dll,一直報(bào)錯(cuò):
%1 is not a valid Win32 application.
就懷疑是否是dll出了問(wèn)題,使用C++調(diào)用,正常運(yùn)行,排除dll的問(wèn)題,然后懷疑是否是golang調(diào)用方法問(wèn)題,這里簡(jiǎn)要說(shuō)一下golang調(diào)用dll的三種方法,使用了C語(yǔ)言編寫了一個(gè)最基本的dll,只包含helloword函數(shù)
void helloword(void) { printf("Hello, World!\n"); }
第一種,直接使用syscall庫(kù)調(diào)用,注意在用完后釋放
const HELLODLLPATH = `C:\gopath\src\helloword_dll\libhelloword.dll`
func Hello1() { helloDll, e := syscall.LoadLibrary(HELLODLLPATH) if e != nil { panic(e) } helloword, e := syscall.GetProcAddress(helloDll, "helloword") if e != nil { panic(e) } _, _, er := syscall.Syscall(helloword, 0, 0, 0, 0) if er != 0 { panic(er) } e = syscall.FreeLibrary(helloDll) if e != nil { panic(e) } }
第二種,使用syscall.NewLazyDLL()來(lái)調(diào)用,這種方式最為簡(jiǎn)潔,后面主要使用這種方式
func Helloword2() { helloDll := syscall.NewLazyDLL(HELLODLLPATH) hello := helloDll.NewProc("helloword") hello.Call() }
第三種,使用syscall.MustLoadDLL(),和第二種類似
func Helloword3() { helloDll := syscall.MustLoadDLL(HELLODLLPATH) hello := helloDll.MustFindProc("helloword") _, _, _ = hello.Call() }
介紹完golang這三種調(diào)用dll的方式后,回到遇到的問(wèn)題,采用這三種方式測(cè)試golang調(diào)用dll是否有問(wèn)題,結(jié)果三種方式均成功調(diào)用,線索中斷,這個(gè)時(shí)候就只能懷疑最開(kāi)始的dll和golang的是否匹配,通過(guò)查詢資料,發(fā)現(xiàn)之前的dll是32位,而golang的環(huán)境為amd64,此時(shí)通過(guò)goland設(shè)置編譯環(huán)境為386,并且把cgo打開(kāi)
SET GOARCH=386 SET CGO_ENABLED=1
終于,成功調(diào)用!
第二個(gè)問(wèn)題,就是調(diào)用dll的參數(shù)傳遞,這里用syscall.NewLazyDLL()來(lái)調(diào)用,目標(biāo)dll有一個(gè)識(shí)別圖像的方法,總共四個(gè)參數(shù),第一個(gè)是一個(gè)id,前面調(diào)用返回的,第二個(gè)是圖像數(shù)據(jù)指針,第三個(gè)圖像長(zhǎng)度,第四個(gè)識(shí)別方式,返回是C語(yǔ)言字符串,具體調(diào)用如下
func IntPtr(n int) uintptr { return uintptr(n) } func BytesPtr(s []byte) uintptr { return uintptr(unsafe.Pointer(&s[0])) } func CnnDll2() { cnnDll := syscall.NewLazyDLL(CNNDLLPATH) //載入 CNN_init := cnnDll.NewProc("CNN_init") bin := OpenBin() id, _, _ := CNN_init.Call(BytesPtr(bin), IntPtr(len(bin)), 0, 0, IntPtr(2), IntPtr(5)) CNN_recognition := cnnDll.NewProc("CNN_recognition") img := OpenImg() //識(shí)別 ret, _, _ := CNN_recognition.Call(id, BytesPtr(img), IntPtr(len(img)), IntPtr(2)) var recode []byte for i := 0; true; i++ { tmp := *(*byte)(unsafe.Pointer(ret + uintptr(i))) if tmp != 0 { recode = append(recode, tmp) } else { break } } fmt.Println("#ret", recode, string(recode)) }
這里返回的字符串是C格式的,和golang的類型底層內(nèi)存模型不同,所以就是按照C的方式,移動(dòng)指針,直到找到'\0',字符串結(jié)束,但是總覺(jué)得這種方式并非最好的方法,通過(guò)查詢資料,找到了自認(rèn)為比較科學(xué)的轉(zhuǎn)換方式,使用CGO的類型,如下
import "C" reStr := C.GoString((*C.char)(unsafe.Pointer(ret)))
C.GoString()的參數(shù)必須是 *C.char ,這里使用了cgo,正如前面所述,需開(kāi)啟cgo環(huán)境
到此這篇關(guān)于golang 交叉編譯C++ dll配置文件的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)golang 交叉編譯C++ dll配置內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
提升Go語(yǔ)言開(kāi)發(fā)效率的小技巧實(shí)例(GO語(yǔ)言語(yǔ)法糖)匯總
這篇文章主要介紹了提升Go語(yǔ)言開(kāi)發(fā)效率的小技巧匯總,也就是Go語(yǔ)言的語(yǔ)法糖,掌握好這些可以提高我們的開(kāi)發(fā)效率,需要的朋友可以參考下2022-11-11Golang?HTTP服務(wù)超時(shí)控制實(shí)現(xiàn)原理分析
這篇文章主要介紹了Golang?HTTP服務(wù)超時(shí)控制實(shí)現(xiàn)原理,HTTP服務(wù)的超時(shí)控制是保障服務(wù)高可用性的重要措施之一,由于HTTP服務(wù)可能會(huì)遇到網(wǎng)絡(luò)延遲,資源瓶頸等問(wèn)題,因此需要對(duì)請(qǐng)求進(jìn)行超時(shí)控制,以避免服務(wù)雪崩等問(wèn)題,需要的朋友可以參考下2023-05-05Golang?中的?strconv?包常用函數(shù)及用法詳解
strconv是Golang中一個(gè)非常常用的包,主要用于字符串和基本數(shù)據(jù)類型之間的相互轉(zhuǎn)換,這篇文章主要介紹了Golang中的strconv包,需要的朋友可以參考下2023-06-06Go語(yǔ)言使用sqlx操作數(shù)據(jù)庫(kù)的示例詳解
sqlx?是?Go?語(yǔ)言中一個(gè)流行的第三方包,它提供了對(duì)?Go?標(biāo)準(zhǔn)庫(kù)?database/sql?的擴(kuò)展,本文重點(diǎn)講解?sqlx?在?database/sql?基礎(chǔ)上擴(kuò)展的功能,希望對(duì)大家有所幫助2023-06-06Go-RESTful實(shí)現(xiàn)下載功能思路詳解
這篇文章主要介紹了Go-RESTful實(shí)現(xiàn)下載功能,文件下載包括文件系統(tǒng)IO和網(wǎng)絡(luò)IO,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-10-10Go結(jié)合Gin導(dǎo)出Mysql數(shù)據(jù)到Excel表格
本文主要介紹了Go結(jié)合Gin導(dǎo)出Mysql數(shù)據(jù)到Excel表格,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08