MATLAB массив libpointer

0

В настоящее время я разрабатываю оболочку для библиотеки C++, поэтому ее можно использовать в MATLAB. Я хочу, чтобы мои объекты C++ были в MATLAB, чтобы пользователь мог что-то с ними делать. На самом деле я бросаю те C++ объекты в void * потому что MATLAB поддерживает только заголовки C. Эти функции C выглядят следующим образом:

__declspec(dllexport) void *getPtr (int someArgument);

В MATLAB я называю такие функции:

ptr = calllib('LibName', 'getPtr', 42);

В MATLAB ptr теперь является <1x1 lib.pointer>. Я ничего не могу с этим сделать, чтобы передать его другой функции C, например:

__declspec(dllexport) int doSomethingWithPtr (void *ptr);

Поэтому я result = calllib('LibName', 'doSomethingWithPtr', ptr); в MATLAB, который отлично работает и выполняет эту функцию с указателем как аргументом. (Я отлаживал код C, а указатель такой же, как тот, который возвращался из getPtr.

Для моей функции C требуется более одного указателя для работы, как это предусмотрено библиотекой C++. Я уже передал числовые данные в матрицах MATLAB в C, которые отлично работают с типом C mxArray (см. Http://www.mathworks.de/de/help/matlab/apiref/mxarray.html). Для передачи нескольких указателей на CI был сконструирован массив MATLAB lib.pointer следующим образом:

A = [];

for i = 1:10
    ptr = calllib('LibName', 'getPtr', i);
    A = [A, ptr];    
end

И я __declspec(dllexport) int doSomethingWithPtrArray (mxArray *ptrarr); другую функцию C (__declspec(dllexport) int doSomethingWithPtrArray (mxArray *ptrarr);) в MATLAB:

ptr = calllib('LibName', 'doSomethingWithPtrArray', A);

Внутри функции C я получаю правильные размеры массива с помощью mxGetN(ptrarr) и mxGetM(ptrarr). Я также могу получить указатель данных с помощью:

void *mexPtr = mxGetData(ptrarr);

Проблема в том, что mexPtr и следующие указатели указывают на местоположения в памяти, которую я даже не выделял и не знал раньше. Возможно, MATLAB делает некоторую интеллектуальную упаковку при вызове функции с void * и не делает этого, когда я передаю массив. (Я думаю, что получаю адреса в lib.pointer оболочки MATLAB lib.pointer?)

У кого-нибудь есть ключ (или обходной путь), как я получаю правильные указатели из mxArray, поэтому я могу сразу оценить несколько указателей?

Теги:
arrays

1 ответ

0
Лучший ответ

Поскольку я не нашел "красивого" решения, я построил вспомогательный метод в C++, который позволяет мне создать собственный вектор:

void *buildClassifierVectorBase(void *vector, void *classifier)
{
    typedef IClassifierManager<input_dtype, feature_dtype, annotation_dtype> class_man_t;

    std::vector<std::shared_ptr<class_man_t>> *classMgrs;

    if (vector == nullptr)
    {
        classMgrs = new std::vector<std::shared_ptr<class_man_t>>();            
    } 
    else
    {
        classMgrs = static_cast<std::vector<std::shared_ptr<class_man_t>> *>(vector);
    }

    class_man_t *cls = static_cast<class_man_t *>(classifier);
    classMgrs->push_back(std::shared_ptr<class_man_t>(cls));        

    return static_cast<void *>(classMgrs);  
}

Этот метод, который я могу использовать в MATLAB для создания этого вектора указателей, таких как:

ptr1 = calllib('LibName', 'getPtr', 42);
ptr2 = calllib('LibName', 'getPtr', 43);
ptr3 = calllib('LibName', 'getPtr', 44);

vector = calllib('LibName', 'buildClassifierVectorBase', libpointer, ptr1);
vector = calllib('LibName', 'buildClassifierVectorBase', vector, ptr2);
vector = calllib('LibName', 'buildClassifierVectorBase', vector, ptr3);

Теперь я могу вызвать свой метод doSomethingWithPtrArray:

ptr = calllib('LibName', 'doSomethingWithPtrArray', vector);

Это решение работает, но не самое приятное...

Ещё вопросы

Сообщество Overcoder
Наверх
Меню