0

我尝试在 C++ 中添加多标题到 edsdk 开发。但是在“takePictures()”中执行“takeSinglePicture()”时代码卡住了,相机甚至不会拍一张照片。如何解决这个问题。代码在这里。

void CameraControl::takePictures(int n,int time) {
    openSession();
    CTimer timer;
    for (int i = 0; i < n; i++) {
        timer.start();
        std::cout<<std::this_thread::get_id()<<endl;
        takeSinglePicture();
        int t = timer.stop();
        if (t < time)  std::this_thread::sleep_for(std::chrono::milliseconds(time-t));
        std::cout << t << std::endl;
    }
   closeSession();

}


void CameraControl::takePicturesMT(int n,int time) {
    std::cout << std::this_thread::get_id() << endl;
    std::thread cameraThread([&] {CameraControl::takePictures(n,time); });
    cameraThread.join();
}

void CameraControl::takeSinglePicture() {
    EdsSendCommand(theCamera, kEdsCameraCommand_PressShutterButton, 1); // Half
    EdsSendCommand(theCamera, kEdsCameraCommand_PressShutterButton, 3); // Completely
    EdsSendCommand(theCamera, kEdsCameraCommand_PressShutterButton, 0); // Off

}
4

1 回答 1

0

一般来说,Canon SDK 不是线程安全的,在不同线程上调用 SDK 函数之前,您需要在 Windows 上调用 CoInitializeEx(并确保没有同时执行其他命令)。

在这种特定情况下,问题很可能是您在调用 takePicturesMT 的同一线程上初始化了 Canon SDK。Canon SDK 使用初始化线程作为主线程并在那里执行所有命令。这意味着您尝试调用 takeSinglePicture 命令,该命令尝试在主线程上执行该命令,并且主线程等待 takePictures 线程完成 -> 死锁。

对此的解决方案是要么不等待线程完成(没有 cameraThread.join),要么在不同的线程上初始化 SDK。第二种解决方案要困难得多,因为您需要实现自己的消息泵(使用 EdsGetEvent 函数)并小心调用 SDK 函数的位置。它也不适用于 macOS,因为 SDK 主线程始终是应用程序主线程(无论您从哪里初始化)。

于 2016-10-27T21:35:23.123 回答