1

Using MATLAB Compiler Runtime (mcr) i have created dll of the a matlab file. I can use the function and pass all the variables to the function easily and without any problem.

My problem is when I have a class with "mwArray" as a variable in it, like:

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

class MModel{

int x;
mwArray y;
};

and then I create an object from it, application in run-time throws an exception in "mclcppclass.h" header file:

Access violation executing location 0X0000000000. 

It would be quite expensive to wrap and convert all input files to the matlab format every time that I want to call those functions, therefore was wondering is there any solution for this problem?

Thanks,

Amro
  • 123,847
  • 25
  • 243
  • 454
Ishmael mp
  • 21
  • 1
  • 3
  • Would it make sense to try making y a pointer to an mwArray, and then calling new in the constructor? – Lukeclh Sep 19 '14 at 15:14
  • did you remember to initialize the MCR runtime (`mclInitializeApplication`) and library (`libXXXInitialize`) **before** using any of it? You have to be careful about the order of how things are constructed when you have classes.. – Amro Sep 19 '14 at 18:25
  • Using pointer didn't work actually! and yep, I did initialized the application and lib first! I can use them in a function easily, but I should pass them all the time to matlab format that makes it uncomfortable! – Ishmael mp Sep 19 '14 at 19:30

2 Answers2

1

Thanks, my problem has been solved actually! the issue is regarding the fact that initialization should be done before creating any instance of the class which contains mwArray object.

For example the following code is gonna crash at the beginning, :

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;
} 

but if you put the initialization part before getting instance from Class2, everything will be fine. In addition, you can not have an instance of the Class2 out of the main too!

Cheers,

Ishmael mp
  • 21
  • 1
  • 3
0

I tried with a simple example on my end (I'm reusing a previous example of mine), but I cannot reproduce the problem.

The MATLAB function we are packaging is the following:

MyAdd.m

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

Compiled into a C++ shared library using mcc compiler:

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

Next here is a C++ program to test the library. I created a class that holds two mwArray instances:

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;
}

The above runs just fine:

>> mbuild testMyAdd.cpp libMyAdd.lib -v
C:\> testMyAdd.exe
a + b =  
     6    10 
     8    12 
Community
  • 1
  • 1
Amro
  • 123,847
  • 25
  • 243
  • 454
  • That's great actually! but here is the problem: put the "MyClass obj;" out of your main! or in another class as an object from "MyClass" class. You will have error that's out of nowhere! – Ishmael mp Sep 25 '14 at 16:52
  • @Ishmaelmp: Global variables are initialized as the program starts **BEFORE** the main function gets a chance to run, so the constructor of `MyClass` would run before the MCR is initialized (which is bad!).. Like I previously said in the comments, you have to be careful about the order of initialization of things... You'll have to modify the class `MyClass` to manage its own dependencies, by using some sort of static members to ensure `mclInitializeApplication` is called first, prior to the class being instantiated – Amro Sep 26 '14 at 12:26