Пользовательский распределитель памяти для OpenCV

Можно ли установить собственный распределитель для OpenCV 2.3.1? У меня создан пул памяти, и я хочу, чтобы OpenCV использовал этот пул для того, что ему нужно.

Это возможно? Если да, то как это можно сделать?

Обновлено:

Я сделал некоторые изменения с момента последнего ответа, но у меня все еще есть некоторые проблемы. Это код, который у меня есть сейчас:

CvAllocFunc allocCV() 
{ 
     return (CvAllocFunc) MEMPOOL->POOLalloc(sz); 
}

CvFreeFunc deallocCV()
{
    return (CvFreeFunc) MEMPOOL->POOLfree(ptr);
}

...

cvSetMemoryManager(allocCV(),deallocCV(),data);

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

Только что узнал: версия OpenCV, которую я использую (2.3.1), выдает ошибку при использовании cvSetMemoryManager. Причина в его исходном коде:

void cvSetMemoryManager( CvAllocFunc, CvFreeFunc, void * )
{
    CV_Error( -1, "Custom memory allocator is not supported" );
}

Я был очень разочарован этим. Думаю, я больше не могу использовать собственный пул памяти с OpenCV!


person André    schedule 22.05.2012    source источник


Ответы (1)


Прямо из документов

http://opencv.willowgarage.com/documentation/c/core_utility_and_system_functions_and_macros.html#setmemorymanager

Использовать

void cvSetMemoryManager(CvAllocFunc allocFunc=NULL, CvFreeFunc freeFunc=NULL, void* userdata=NULL)

функция.

Ваш код

cvSetMemoryManager(allocCV(),deallocCV(),data);

неправильно.

Посмотрите, что происходит: вы вызываете функции allocCV и DeallocCV (они возвращают некоторый указатель, который незаметно преобразуется в cvAllocFunc)!

И это только начало. См. документы для семантики alloc/dealloc. Вы должны написать allocCV/deallocCV с правильными подписями.

void* CV_CDECL allocCV(size_t size, void* userdata)
{
     return ((YourMemPoolTypeWhichIDoNotKnow*)userdata)->POOLalloc(size);
}

int CV_CDECL deallocCV(void* pptr, void* userdata)
{
    return ((YourMemPoolTypeWhichIDoNotKnow*)userdata)->POOLfree(pptr);
}

а затем передайте свой MEMPOOL в параметре userdata:

cvSetMemoryManager(&allocCV, &deallocCV, (void*)MEMPOOL);

Это стандартный способ для библиотеки предоставлять обратные вызовы пользователя.

person Viktor Latypov    schedule 22.05.2012
comment
Я уже пробовал, но не смог заставить его работать. Я не знаю, делал ли я что-то не так, или это из-за версии opencv. Я использую OpenCV 2.3.1, и эта функция из 2.1, и я не нашел эквивалента для своей версии. - person André; 22.05.2012
comment
Хорошо, я попробовал способ, описанный выше, и он компилируется без ошибок, но во время выполнения он выдает исключение при попытке запустить cvSetMemoryManager. Что-то вроде: исключение первого шанса в 0x7c... :\ есть идеи? - person André; 22.05.2012
comment
К этому может привести множество причин. Вы используете OpenCV в DLL? Убедитесь, что DLL и ваш проект имеют идентичные библиотеки времени выполнения. - person Viktor Latypov; 22.05.2012
comment
В проекте, над которым я работаю, используется OpenCV, и он работает хорошо, но когда я пытаюсь выполнить cvSetMemoryManager, он выдает ошибку... В любом случае, это может быть проблемой моего кода. Спасибо за вашу помощь - person André; 22.05.2012
comment
Я просматриваю код для 2.4.2 и обнаружил, что cvSetMemoryManager() ничего не делает, кроме того, что выдает исключение со строкой пользовательского распределителя памяти, которая не поддерживается. Хм... кажется, сопровождающие удалили эту функцию примерно из 2.x. :( - person Joonhwan; 19.10.2012