我正在编写一个包来控制使用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