我尝试在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
}
答案 0 :(得分:0)
一般情况下,Canon SDK不是线程安全的,在调用另一个线程上的SDK函数之前,您需要在Windows上调用CoInitializeEx(并确保不会同时执行其他命令)。
在这种特定情况下,问题很可能是你在调用takePicturesMT的同一个线程上初始化了Canon SDK。 Canon SDK使用初始化线程作为主线程并在那里执行所有命令。这意味着您尝试调用takeSinglePicture命令,该命令尝试在主线程上执行命令,主线程等待takePictures线程完成 - &gt;死锁。
对此的解决方案是要么不等待线程完成(没有cameraThread.join)要么在另一个线程上初始化SDK。第二种解决方案相当困难,因为那时你需要实现自己的消息泵(使用EdsGetEvent函数),并且要小心你调用SDK函数的位置。它也不适用于macOS,因为SDK主线程总是应用程序主线程(无论你从哪里初始化)。