摘要:,語言實現儀表控制可以采用種方式,一種是使用編程,使用驅動自帶的文件進行開發,但是感覺怪怪的,感覺這樣還不如直接使用進行開發,還有現成的版本可用。硬件信息為查詢儀表清單。類型轉換是必須的,的是由首字符指針長度組成。
golang,go語言實現儀表控制可以采用2種方式,一種是使用CGO編程,使用驅動自帶的VISA.H文件進行開發,但是感覺怪怪的,感覺這樣還不如直接使用C進行開發,還有現成的版本可用。因此本文使用的是調用dll的方式來進行。
viOpenDefaultRM:打開設備管理器,初始化。
func?OpenRM()?uintptr?{????VISA32?:=?syscall.NewLazyDLL("visa32.dll")????viOpenDefaultRM?:=?VISA32.NewProc("viOpenDefaultRM")????ret,?_,?_?:=?viOpenDefaultRM.Call(uintptr(unsafe.Pointer(&resourceManager)))????fmt.Println("硬件信息為:",?resourceManager)????return?ret}
viFindRsrc:查詢儀表清單。
func?FindRsrc()?bool?{????VISA32?:=?syscall.NewLazyDLL("visa32.dll")????viFindRsrc?:=?VISA32.NewProc("viFindRsrc")????var?list?int?=?0????instrDor?:=?getMyString("?*")????var?data?[180]byte????retcnt?:=?0????ret,?_,?_?:=?viFindRsrc.Call(uintptr(resourceManager),?uintptr(unsafe.Pointer(instrDor.Str)),?uintptr(unsafe.Pointer(&list)),?uintptr(unsafe.Pointer(&retcnt)),?uintptr(unsafe.Pointer(&data)))????if?ret?!=?0?{????????fmt.Println("查詢代碼:",?ret)????????return?false????}????fmt.Println("查詢成功->")????viFindNext?:=?VISA32.NewProc("viFindNext")????viFindNext.Call(uintptr(list),?uintptr(unsafe.Pointer(&data)))????s?:=?string(Bytes2string(data))????viClose?:=?VISA32.NewProc("viClose")????viClose.Call(uintptr(list))????fmt.Println(s)????return?true}
viOpen:使用地址打開儀表。
????instrDor?:=?getMyString(addr)????VISA32?:=?syscall.NewLazyDLL("visa32.dll")????viOpen?:=?VISA32.NewProc("viOpen")????var?instr?int?=?0????ret,?_,?_?:=?viOpen.Call(uintptr(resourceManager),?uintptr(unsafe.Pointer(instrDor.Str)),?uintptr(0),?uintptr(0),?uintptr(unsafe.Pointer(&instr)))????if?instr?==?0?{????????return?"打開儀器失敗,錯誤代碼為:"?+?fmt.Sprint(ret)????}
viClose:關閉設備管理器,關閉儀器清單,關閉打開的儀表(可以理解為釋放內存)上面的3個函數都要。
viPrintf/viScanf:發送和接收儀表的數據
//?發送信息給儀表//?addr為儀器地址,m為需要發送的信息,如GPIB0::15::INSTR,send:DISP?TXfunc?SendMsg(addr,?m?string)?string?{????instrDor?:=?getMyString(addr)????VISA32?:=?syscall.NewLazyDLL("visa32.dll")????viOpen?:=?VISA32.NewProc("viOpen")????var?instr?int?=?0????ret,?_,?_?:=?viOpen.Call(uintptr(resourceManager),?uintptr(unsafe.Pointer(instrDor.Str)),?uintptr(0),?uintptr(0),?uintptr(unsafe.Pointer(&instr)))????if?instr?==?0?{????????return?"打開儀器失敗,錯誤代碼為:"?+?fmt.Sprint(ret)????}????m?=?m?+?"/n"????msg?:=?getMyString(m)????viPrintf?:=?VISA32.NewProc("viPrintf")????ret2,?_,?_?:=?viPrintf.Call(uintptr(instr),?uintptr(unsafe.Pointer(msg.Str)))????viClose?:=?VISA32.NewProc("viClose")????viClose.Call(uintptr(instr))????if?ret2?==?0?{????????return?"信息發送成功!---"?+?m????}????return?"發送失敗,代碼為:"?+?fmt.Sprint(ret2)}//?發送信息給儀表,并等待儀表返回數據。func?ReadData(addr,?m?string)?string?{????instrDor?:=?getMyString(addr)????VISA32?:=?syscall.NewLazyDLL("visa32.dll")????viOpen?:=?VISA32.NewProc("viOpen")????var?instr?int?=?0????ret,?_,?_?:=?viOpen.Call(uintptr(resourceManager),?uintptr(unsafe.Pointer(instrDor.Str)),?uintptr(0),?uintptr(0),?uintptr(unsafe.Pointer(&instr)))????if?instr?==?0?{????????return?"打開儀器失敗,錯誤代碼為:"?+?fmt.Sprint(ret)????}????m?=?m?+?"/n"????msg?:=?getMyString(m)????viPrintf?:=?VISA32.NewProc("viPrintf")????viPrintf.Call(uintptr(instr),?uintptr(unsafe.Pointer(msg.Str)))????readFmt?:=?getMyString("%t")????viScanf?:=?VISA32.NewProc("viScanf")????var?data?[180]byte????viScanf.Call(uintptr(instr),?uintptr(unsafe.Pointer(readFmt.Str)),?uintptr(unsafe.Pointer(&data)))????s?:=?string(Bytes2string(data))????viClose?:=?VISA32.NewProc("viClose")????viClose.Call(uintptr(instr))????return?s}// 返回的數據后面有很多個0,截斷處理會更好些。func Bytes2string(data [180]byte) string { for i := 0; i < len(data); i++ { if data[i] == 10 || data[i] == 0 { return string(data[:i]) } } return string(data[:])}
go語言的string與C的string是有所區別的,gostring的結構是首字符的指針+長度,而Cstring的結構只有首字符指針,然后讀取時順序讀到字符0為止。因此在傳遞中要進行轉換,比如:
使用CGO使用C.CString進行轉換,但這個方式會導致內存不能釋放。
文中采用了另一種方式,改造結構體的方式,因此采用了另一種結構體MyString。
//?新建類型,代替C.CString//?C.CString使用會產生拷貝,并不會自動釋放,需要進行free。type?MyString?struct?{????Str?unsafe.Pointer????Len?int}//類型轉換//?/x00是必須的,go的string是由首字符指針+長度組成。而C的string只有首字符指針,長度由字節0來確定,即順序讀,直到讀到0。/x00即代表字符0func?getMyString(s?string)?*MyString?{????s?=?s?+?"/x00"????return?(*MyString)(unsafe.Pointer(&s))}
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/121761.html
摘要:如果說是主要針對和的三個關鍵信息成長和,那么上午則是專注的企業級應用。將以季度為單位進行版本更新。天的已經接近尾聲,金融保險兩大客戶現身說法,企業級初現崢嶸,從技術到商業落地,從開發者到企業級用戶,容器世界的大門已經打開。 If the container ecosystem succeeds, Docker succeeds. showImg(https://segmentfault...
摘要:為了了解被這種木馬感染的地區分布情況,我們分析了相關檢測部分的運行狀況。受到感染影響最嚴重的區域為中南美的哥倫比亞委內瑞拉秘魯墨西哥阿根廷以及亞洲的菲利賓越南和歐洲的波蘭。通信協議目前發現的服務器有。響應結構采用以分割的字符串數組的形式。 在最近幾個星期里的AVAST惡意樣本分析名單中,Win32/64:Napolar擁有極高的文件和網絡屏蔽率。另外,我們發現了被冠以Solarbot名...
摘要:原文出自聽云技術博客斷斷續續寫了將近一個月,聽云第一版數據庫管理平臺終于寫完了,期間來來回回的改了好多次小毛病,現在已經部署到生產環境上去了。主機管理這里主要是主機列表管理和業務組列表管理。 原文出自【聽云技術博客】:http://blog.tingyun.com/web/article/detail/600 斷斷續續寫了將近一個月,聽云第一版數據庫管理平臺終于寫完了,期間來來回回的改...
摘要:最終我厭倦了這樣的方式,雖然很懷念完備的功能,我還是開始使用內聯匯編來解決問題。禁用棧緩沖區安全檢查。為了使微軟編譯器在棧上動態的分配字符以便重定位,你需要如下處理你會發現,我將字符串聲明為字符數組的形式。 背景 有時候程序員們需要寫一段獨立于位置操作的代碼,可當作一段數據寫到其他進程或者網絡中去。該類型代碼在它誕生之初就被稱為shellcode,在軟件中黑客們以此獲取到shell權...
閱讀 3195·2021-11-18 10:02
閱讀 1446·2021-10-12 10:08
閱讀 1235·2021-10-11 10:58
閱讀 1269·2021-10-11 10:57
閱讀 1167·2021-10-08 10:04
閱讀 2121·2021-09-29 09:35
閱讀 773·2021-09-22 15:44
閱讀 1268·2021-09-03 10:30