我正在为一款DSLR相机开发SDK,该相机需要以下操作指南:
开发Windows应用程序时,请注意对每个线程进行COM初始化以便从除主线程以外的线程访问相机。要创建用户线程并从该线程访问相机,请确保在线程开始时执行CoInitializeEx(NULL, COINIT_APARTMENTTHREADED),并在结束时执行CoUnInitialize()。下面是示例代码。这也适用于从其他线程控制EdsVolumeRef或EdsDirectoryItemRef对象,而不仅仅是EdsCameraRef。
void TakePicture(EdsCameraRef camera)
{
// Executed by another thread
HANDLE hThread = (HANDLE)_beginthread(threadProc, 0, camera);
// Block until finished
::WaitForSingleObject( hThread, INFINITE );
}
void threadProc(void* lParam)
{
EdsCameraRef camera = (EdsCameraRef)lParam;
CoInitializeEx( NULL, COINIT_APARTMENTTHREADED );
EdsSendCommand(camera, kEdsCameraCommand_TakePicture, 0);
CoUninitialize();
_endthread();
}
我的应用程序是一个C# WinForms应用程序,通常情况下,我使用托管的线程类和Control.Invoke函数来避免跨线程问题。
由于我没有C#的SDK示例源代码,我的问题是,在标记有[STAThread]属性的应用程序中使用CoInitializeEx是否有用或必要?
我还没有遇到需要让我的应用程序为线程创建新公寓的场景,因此了解线程模型的更多信息将很有帮助。
更新:在阅读了一些关于公寓和COM的文章之后,它开始变得有点明朗起来。现在我想知道.NET托管线程类的默认值是什么,我们能否以托管方式为每个线程指定公寓模型而不需要P/Invoke?