欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

golang 交叉編譯C++ dll配置文件的實(shí)現(xiàn)

 更新時(shí)間:2025年07月25日 09:43:44   作者:譜寫  
本文探討了在64位環(huán)境下調(diào)用32位C++ DLL的的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

調(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)文章

  • golang?Strings包使用總結(jié)

    golang?Strings包使用總結(jié)

    Go語(yǔ)言在處理字符串時(shí),strings包提供了豐富的函數(shù),如常用的strings.Contains檢查是否包含子串,strings.Join拼接字符串?dāng)?shù)組,strings.Split切割字符串等,熟悉這些函數(shù)能有效提高編程效率,尤其是在算法競(jìng)賽或筆試題中
    2021-03-03
  • win10下go mod配置方式

    win10下go mod配置方式

    這篇文章主要介紹了win10下go mod配置方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-04-04
  • 提升Go語(yǔ)言開(kāi)發(fā)效率的小技巧實(shí)例(GO語(yǔ)言語(yǔ)法糖)匯總

    提升Go語(yǔ)言開(kāi)發(fā)效率的小技巧實(shí)例(GO語(yǔ)言語(yǔ)法糖)匯總

    這篇文章主要介紹了提升Go語(yǔ)言開(kāi)發(fā)效率的小技巧匯總,也就是Go語(yǔ)言的語(yǔ)法糖,掌握好這些可以提高我們的開(kāi)發(fā)效率,需要的朋友可以參考下
    2022-11-11
  • 深入探索Go語(yǔ)言中unsafe包的使用

    深入探索Go語(yǔ)言中unsafe包的使用

    Go語(yǔ)言的unsafe包被譽(yù)為黑科技,它為Go語(yǔ)言提供了底層訪問(wèn)和操控內(nèi)存的能力,本文將深入探討Go語(yǔ)言中unsafe包的使用方法和注意事項(xiàng),需要的可以參考一下
    2023-04-04
  • Go?error的使用方式詳解

    Go?error的使用方式詳解

    當(dāng)我們需要在Go項(xiàng)目中設(shè)計(jì)error,就不得不先知道Go error幾種常用方法,今天通過(guò)本文給大家介紹Go?error的使用方式詳解,感興趣的朋友一起看看吧
    2022-05-05
  • Golang?HTTP服務(wù)超時(shí)控制實(shí)現(xiàn)原理分析

    Golang?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-05
  • Golang?中的?strconv?包常用函數(shù)及用法詳解

    Golang?中的?strconv?包常用函數(shù)及用法詳解

    strconv是Golang中一個(gè)非常常用的包,主要用于字符串和基本數(shù)據(jù)類型之間的相互轉(zhuǎn)換,這篇文章主要介紹了Golang中的strconv包,需要的朋友可以參考下
    2023-06-06
  • Go語(yǔ)言使用sqlx操作數(shù)據(jù)庫(kù)的示例詳解

    Go語(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-06
  • Go-RESTful實(shí)現(xiàn)下載功能思路詳解

    Go-RESTful實(shí)現(xiàn)下載功能思路詳解

    這篇文章主要介紹了Go-RESTful實(shí)現(xiàn)下載功能,文件下載包括文件系統(tǒng)IO和網(wǎng)絡(luò)IO,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-10-10
  • Go結(jié)合Gin導(dǎo)出Mysql數(shù)據(jù)到Excel表格

    Go結(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

最新評(píng)論