C ++: mwArray как переменная в классе c ++

0

Используя MATLAB Compiler Runtime (mcr), я создал dll файла matlab. Я могу использовать функцию и передавать все переменные функции легко и без проблем.

Моя проблема в том, что у меня есть класс с "mwArray" как переменная в нем, например:

#include <samplemmfile.h>
#include <mclmcr.h>
#include <stdio.h>

class MModel{

int x;
mwArray y;
};

и затем я создаю из него объект, приложение во время выполнения генерирует исключение в файле заголовка "mclcppclass.h":

Access violation executing location 0X0000000000. 

Было бы довольно дорого обернуть и преобразовать все входные файлы в формат matlab каждый раз, когда я хочу называть эти функции, поэтому было интересно, есть ли какие-либо решения для этой проблемы?

Благодаря,

  • 0
    Имеет ли смысл попытаться сделать указатель ya на mwArray, а затем вызвать new в конструкторе?
  • 0
    вы не забыли инициализировать среду выполнения MCR ( mclInitializeApplication ) и библиотеку ( libXXXInitialize ) перед использованием любого из них? Вы должны быть осторожны с порядком того, как все устроено, когда у вас есть классы.
Показать ещё 1 комментарий
Теги:
matlab-compiler

2 ответа

0

Спасибо, моя проблема была решена на самом деле! проблема заключается в том, что инициализация должна быть выполнена до создания любого экземпляра класса, который содержит объект mwArray.

Например, следующий код сработает с самого начала:

Class1.h:

#include "libInnerProduct.h" 

class Class1
{
public:
Class1()
: a(1, 2, mxDOUBLE_CLASS), b(1, 2, mxDOUBLE_CLASS) {
    double aa[] = {1 , 2};
    double bb[] = {5 , 7};
    a.SetData(aa, 2);
    b.SetData(bb, 2);
}
double innerproduct() {
    mwArray c;
    InnerProd(1, c, a, b);
    return (double)c;
}
private:
mwArray a, b;
};

Class2.h:

 #include "Class1.h" 
 #include <mclmcr.h>
 #include <mclcppclass.h>

class Class2
{
public:
Class2(){
    if (!mclInitializeApplication(NULL,0) || !libInnerProductInitialize())  {
          std::cerr << "failed to initialize" << std::endl;
          exit(1);
    }
    obj=new Class1();
}
~Class2(){
    libInnerProductTerminate();   
    mclTerminateApplication();
}
double inp(){
    return obj->innerproduct();
}
private:
Class1* obj;
};

int main()
{
    Class2 obj;
    double sum = obj.inp();
    std::cout << sum << std::endl;  
    return 0;
} 

но если вы поместите часть инициализации перед тем, как получить экземпляр класса Class 2, все будет хорошо. Кроме того, вы также не можете иметь экземпляр Class2 из основного!

Ура,

0

Я попытался с простым примером на моем конце (я повторно использую предыдущий пример), но я не могу воспроизвести проблему.

Функция MATLAB, которую мы упаковываем, такова:

MyAdd.m

function c = MyAdd(a,b)
    c = a + b;
end

Скомпилирован в общую библиотеку C++ с использованием mcc компилятора:

>> mcc -N -W cpplib:libMyAdd -T link:lib MyAdd.m -v

Далее здесь C++ программа для тестирования библиотеки. Я создал класс, содержащий два экземпляра mwArray:

testMyAdd.cpp

#include "libMyAdd.h"    // generated library

class MyClass
{
  public:
    MyClass()
    : a(2, 2, mxDOUBLE_CLASS, mxREAL), b(2, 2, mxDOUBLE_CLASS, mxREAL) {
        double aa[] = {1.0, 2.0, 3.0, 4.0};
        double bb[] = {5.0, 6.0, 7.0, 8.0};
        a.SetData(aa, 4);
        b.SetData(bb, 4);
    }
    mwArray add() {
        mwArray c;
        MyAdd(1, c, a, b);
        return c;
    }
  private:
    mwArray a, b;
};

int main()
{
    if (!mclInitializeApplication(NULL,0) || !libMyAddInitialize())  {
        std::cerr << "failed to initialize" << std::endl;
        return -1;
    }

    try {
        MyClass obj;
        mwArray sum = obj.add();
        std::cout << "a + b = \n" << sum << std::endl;
    } catch (const mwException& e) {
        std::cerr << e.what() << std::endl;
        return -2;
    } catch (...) {
        std::cerr << "Unexpected error thrown" << std::endl;
        return -3;
    } 

    libMyAddTerminate();   
    mclTerminateApplication();
    return 0;
}

Вышеупомянутое работает просто отлично:

>> mbuild testMyAdd.cpp libMyAdd.lib -v
C:\> testMyAdd.exe
a + b =  
     6    10 
     8    12 
  • 0
    Это здорово на самом деле! но вот проблема: поставь "MyClass obj;" из вашего основного! или в другом классе как объект из класса "MyClass". У вас будет ошибка из ниоткуда!
  • 0
    @Ishmaelmp: глобальные переменные инициализируются при запуске программы ДО того, как основная функция получит шанс на запуск, поэтому конструктор MyClass будет работать до инициализации MCR (что плохо!). Как я уже говорил в комментариях, вы нужно быть осторожным с порядком инициализации вещей ... Вы должны будете изменить класс MyClass чтобы управлять его собственными зависимостями, используя некоторый вид статических членов, чтобы гарантировать, что mclInitializeApplication вызывается, до того, как будет создан экземпляр класса

Ещё вопросы

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