亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

調(diào)用c++ 報%1 is not a valid Win32 application

開發(fā)環(huán)境:

win64位

C++ dll 為32位

首先遇到的坑就是環(huán)境的配置,調(diào)用了一個之前C++寫的dll,一直報錯:

%1 is not a valid Win32 application.

就懷疑是否是dll出了問題,使用C++調(diào)用,正常運行,排除dll的問題,然后懷疑是否是golang調(diào)用方法問題,這里簡要說一下golang調(diào)用dll的三種方法,使用了C語言編寫了一個最基本的dll,只包含helloword函數(shù)

void helloword(void) {
    printf("Hello, World!\n");
}

第一種,直接使用syscall庫調(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()來調(diào)用,這種方式最為簡潔,后面主要使用這種方式

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的方式后,回到遇到的問題,采用這三種方式測試golang調(diào)用dll是否有問題,結(jié)果三種方式均成功調(diào)用,線索中斷,這個時候就只能懷疑最開始的dll和golang的是否匹配,通過查詢資料,發(fā)現(xiàn)之前的dll是32位,而golang的環(huán)境為amd64,此時通過goland設(shè)置編譯環(huán)境為386,并且把cgo打開

SET GOARCH=386
SET CGO_ENABLED=1

終于,成功調(diào)用!

第二個問題,就是調(diào)用dll的參數(shù)傳遞,這里用syscall.NewLazyDLL()來調(diào)用,目標(biāo)dll有一個識別圖像的方法,總共四個參數(shù),第一個是一個id,前面調(diào)用返回的,第二個是圖像數(shù)據(jù)指針,第三個圖像長度,第四個識別方式,返回是C語言字符串,具體調(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()
	//識別
	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的方式,移動指針,直到找到'\0',字符串結(jié)束,但是總覺得這種方式并非最好的方法,通過查詢資料,找到了自認(rèn)為比較科學(xué)的轉(zhuǎn)換方式,使用CGO的類型,如下

import "C"
reStr := C.GoString((*C.char)(unsafe.Pointer(ret)))

C.GoString()的參數(shù)必須是 *C.char ,這里使用了cgo,正如前面所述,需開啟cgo環(huán)境

到此這篇關(guān)于golang 交叉編譯C++ dll配置文件的實現(xiàn)的文章就介紹到這了,更多相關(guān)golang 交叉編譯C++ dll配置內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Go 驗證字符串中是否包含中文(推薦)

    Go 驗證字符串中是否包含中文(推薦)

    這篇文章主要介紹了Go 驗證字符串中是否包含中文,本文通過實例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-01-01
  • Go實現(xiàn)set類型的示例代碼

    Go實現(xiàn)set類型的示例代碼

    本文主要介紹了Go實現(xiàn)set類型的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • go語言中range用法

    go語言中range用法

    這篇文章主要介紹了go語言中range用法,實例分析了Go語言中range的功能及使用技巧,需要的朋友可以參考下
    2015-03-03
  • 淺析Golang中變量與常量的聲明與使用

    淺析Golang中變量與常量的聲明與使用

    變量、常量的聲明與使用是掌握一門編程語言的基礎(chǔ),這篇文章主要為大家詳細(xì)介紹了Golang中變量與常量的聲明與使用,需要的可以參考一下
    2023-04-04
  • Go中使用操作符進行數(shù)學(xué)運算的示例代碼

    Go中使用操作符進行數(shù)學(xué)運算的示例代碼

    在編程中有效地執(zhí)行數(shù)學(xué)運算是一項需要開發(fā)的重要技能,本文主要介紹了Go中使用操作符進行數(shù)學(xué)運算的示例代碼,具有一定的參考價值,感興趣的可以了解一下
    2023-10-10
  • Golang中多個線程和多個協(xié)程的使用區(qū)別小結(jié)

    Golang中多個線程和多個協(xié)程的使用區(qū)別小結(jié)

    本文主要介紹了Golang中多個線程和多個協(xié)程的使用區(qū)別小結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-06-06
  • go語言單例模式(Singleton)實例分析

    go語言單例模式(Singleton)實例分析

    這篇文章主要介紹了go語言單例模式(Singleton),實例分析了單例模式的原理與Go語言的實現(xiàn)技巧,需要的朋友可以參考下
    2015-03-03
  • go微服務(wù)PolarisMesh源碼解析服務(wù)端啟動流程

    go微服務(wù)PolarisMesh源碼解析服務(wù)端啟動流程

    這篇文章主要為大家介紹了go微服務(wù)PolarisMesh源碼解析服務(wù)端啟動流程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-01-01
  • golang語言如何將interface轉(zhuǎn)為int, string,slice,struct等類型

    golang語言如何將interface轉(zhuǎn)為int, string,slice,struct等類型

    這篇文章主要介紹了golang語言如何將interface轉(zhuǎn)為int, string,slice,struct等類型,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-12-12
  • Go語言中panic的實現(xiàn)示例

    Go語言中panic的實現(xiàn)示例

    Go語言中panic用于處理不可恢復(fù)的嚴(yán)重錯誤,觸發(fā)后終止函數(shù)并展開堆棧,需與defer配合使用recover捕獲,避免程序崩潰,具有一定的參考價值,感興趣的可以了解一下
    2025-08-08

最新評論