Блоки Objective-C, переменные C ++ и асинхронный код - PullRequest
1 голос
/ 07 декабря 2011

У меня проблема при склеивании переменных c ++ с асинхронным кодом obj-c на iOS.

Настоящая проблема заключается в асинхронном коде, я использую сторонние библиотеки, встроенные в C ++которые ожидают ссылки на объекты, например:


- (void) processFrame:(cv::Mat &)mat;

Моя проблема реальная проблема заключается в том, как это вызвать?Мне нужно создать объект c ++ в другом потоке и передать его в асинхронный код, примерно так:


__block cv::Mat mat(videoRect.size.height, videoRect.size.width, CV_8UC4, baseaddress, 0);
dispatch_async(dispatch_get_main_queue(), ^{
            [self processFrame:mat];
        });

, которые выдают ошибку (неверный доступ), проблема в (я думаю)объект уничтожается до запуска метода, поэтому я попытался создать объект в куче:


__block cv::Mat *mat= new cv::Mat(videoRect.size.height, videoRect.size.width, CV_8UC4, baseaddress, 0);
dispatch_async(dispatch_get_main_queue(), ^{
            [self processFrame:(*mat)];
        });

И все же:


__block cv::Mat *mat= new cv::Mat(videoRect.size.height, videoRect.size.width, CV_8UC4, baseaddress, 0);
dispatch_async(dispatch_get_main_queue(), ^{
            [self processFrame:mat];
        });

Я все время получаю ошибки «Плохой доступ»

Есть идеи?

1 Ответ

2 голосов
/ 07 декабря 2011

Спецификатор __block указывает компилятору не копировать объект для блока, поэтому он не работает. Если вы не переназначаете mat или не пытаетесь предотвратить ненужную операцию сохранения / копирования, вам следует удалить __block.

cv::Mat mat(videoRect.size.height, videoRect.size.width, CV_8UC4, baseaddress, 0);
dispatch_async(dispatch_get_main_queue(), ^{
            [self processFrame:mat];
        });

Примеры, где вы создаете new cv::Mat, могут быть неудачными, потому что вы можете удалять mat слишком рано.

__block cv::Mat *mat= new cv::Mat(videoRect.size.height, videoRect.size.width, CV_8UC4, baseaddress, 0);
dispatch_async(dispatch_get_main_queue(), ^{
            [self processFrame:mat];
            //mat would need to be deleted here
        });
delete mat; //If you are doing this, you will likely get an EXC_BAD_ACCESS
...