我正在編寫一個包來控制使用Go的EDSDK DLL的Canon DSLR。在「LockOSThread」中調用函數GoRoutine
這是一個個人項目相片展臺,在我們的婚禮用在我的合作伙伴的要求,我會很高興地張貼在GitHub上完成時:)。
綜觀使用SDK的其他地方的例子,它不是線程安全的,並且使用線程本地資源,所以我需要確保我從一個單獨的線程使用過程中調用它。雖然這並不理想,但它看起來像Go提供了一個「runtime.LockOSThread」函數來實現這一點,雖然這確實被核心DLL互操作代碼本身調用,所以我將不得不等待並找出是否干擾。
我希望應用程序的其餘部分能夠使用更高級別的接口調用SDK而不用擔心線程,所以我需要一種方法將函數調用請求傳遞給鎖定的線程/ Goroutine以在那裏執行,然後將結果傳回給Goroutine之外的調用函數。
到目前爲止,我已經想出了使用非常廣泛的函數定義使用[]接口{}陣列和回傳,並通過渠道轉發的該工作示例。這會在每次調用時花費大量的輸入/輸出數據,以便從接口數組中返回類型斷言,即使我們知道我們應該提前爲每個函數預期什麼,但它看起來像它會工作。
之前,我投入了大量的時間做這種方式對可能做的最糟糕的方式 - 沒有任何人有任何更好的選擇?
package edsdk
import (
"fmt"
"runtime"
)
type CanonSDK struct {
FChan chan functionCall
}
type functionCall struct {
Function func([]interface{}) []interface{}
Arguments []interface{}
Return chan []interface{}
}
func NewCanonSDK() (*CanonSDK, error) {
c := &CanonSDK {
FChan: make(chan functionCall),
}
go c.BackgroundThread(c.FChan)
return c, nil
}
func (c *CanonSDK) BackgroundThread(fcalls <-chan functionCall) {
runtime.LockOSThread()
for f := range fcalls {
f.Return <- f.Function(f.Arguments)
}
runtime.UnlockOSThread()
}
func (c *CanonSDK) TestCall() {
ret := make(chan []interface{})
f := functionCall {
Function: c.DoTestCall,
Arguments: []interface{}{},
Return: ret,
}
c.FChan <- f
results := <- ret
close(ret)
fmt.Printf("%#v", results)
}
func (c *CanonSDK) DoTestCall([]interface{}) []interface{} {
return []interface{}{ "Test", nil }
}
您的問題可能對於SO來說太複雜。嘗試將其歸結爲代碼中的單個關注點。 – eduncan911