长沙项目关于设备操作遇到的问题及解决
最近被公司派到现场开发,需要通过第三方SDK操作某些设备,期间遇到一些问题
1.某LED走字屏SDK为Com组件,而服务为WCF寄宿在IIS上,由于SDK只支持点阵,需要把字渲染为图片再操作设备。信手写了个用WPF保存图片方法,可WPF需要STA线程,所以还得把设备操作的方法在STA线程里执行,于是
private Thread staThread;
//初始化
staThread = new Thread(new ThreadStart(ThreadStart));
staThread.SetApartmentState(ApartmentState.STA);
//打开设备
staThread.Start();
var dis = Dispatcher.FromThread(staThread);
//线程代码
private void ThreadStart()
{
Dispatcher.Run();
}
//调用工具方法
private object Invoke(Action action)
{
return dispatcher.Invoke(new Action(() =>
{
try
{
action();
}
catch (Exception e)
{
......
}
}), null);
}
//调用
private int DoSomething()
{
return (int)Invoke(() => someCode);
}
2.同样的方法用在另一设备中,操作正常,但回调抛异常
System.ArgumentException was unhandled
HResult=-2147024809
Message=无法跨 AppDomain 传递 GCHandle。
参数名: handle
Source=mscorlib
ParamName=handle
StackTrace:
在 System.Runtime.InteropServices.GCHandle.InternalCheckDomain(IntPtr handle)
在 System.Runtime.InteropServices.GCHandle.FromIntPtr(IntPtr value)
在 System.Runtime.InteropServices.GCHandle.op_Explicit(IntPtr value)
google了一下http://lambert.geek.nz/2007/05/29/unmanaged-appdomain-callback/原来是托管、非托管互操作问题,于是在非托管代码中添加了一个委托一个函数指针声明(非托管为调用方)
//初始化
someCallback_Delegate = gcnew SomeCallbackDelegate(ManagedInstance, &ManagedClass::Callback);
someCallback_Native = (SomeCallbackDelegate)Marshal::GetFunctionPointerForDelegate(someCallback_Delegate).ToPointer();
//调用回调
someCallback_Native(...);