C++:mwArray 作为 C++ 类中的变量

Posted

技术标签:

【中文标题】C++:mwArray 作为 C++ 类中的变量【英文标题】:C++: mwArray as a variable in a c++ class 【发布时间】:2014-09-19 14:30:49 【问题描述】:

使用 MATLAB Compiler Runtime (mcr) 我创建了一个 matlab 文件的 dll。我可以使用该函数并将所有变量轻松传递给该函数,没有任何问题。

我的问题是当我有一个带有“mwArray”作为变量的类时,例如:

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

class MModel

int x;
mwArray y;
;

然后我从它创建一个对象,运行时应用程序在“mclcppclass.h”头文件中引发异常:

Access violation executing location 0X0000000000. 

每次我想调用这些函数时,将所有输入文件打包并转换为 matlab 格式会非常昂贵,因此想知道这个问题有什么解决方案吗?

谢谢,

【问题讨论】:

尝试将 y 设为 mwArray 的指针,然后在构造函数中调用 new 是否有意义? 您是否记得在使用之前初始化 MCR 运行时 (mclInitializeApplication) 和库 (libXXXInitialize)?当你有类时,你必须注意事物的构造顺序。.. 使用指针实际上不起作用!是的,我确实首先初始化了应用程序和库!我可以轻松地在函数中使用它们,但我应该一直将它们传递给 matlab 格式,这会让人不舒服! 【参考方案1】:

谢谢,我的问题实际上已经解决了!问题在于,应该在创建包含 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;
 

但是如果你把初始化部分放在从 Class2 获取实例之前,一切都会好起来的。另外,你不能有一个Class2的实例掉main呢!

干杯,

【讨论】:

【参考方案2】:

我尝试了一个简单的示例(我正在重复使用我的 previous example),但我无法重现该问题。

我们打包的MATLAB函数如下:

MyAdd.m

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

使用mcc编译器编译成C++共享库:

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

【讨论】:

真的很棒!但这里有问题:把“MyClass obj;”出你的主力!或在另一个类中作为“MyClass”类的对象。您将遇到突然出现的错误! @Ishmaelmp:全局变量在程序启动时被初始化BEFORE主函数有机会运行,所以MyClass的构造函数会在MCR初始化之前运行(这很糟糕!).. 就像我之前在 cmets 中所说的那样,您必须注意事物的初始化顺序...您必须修改类 MyClass 以管理其自己的依赖项,使用某种静态成员,以确保在实例化类之前首先调用 mclInitializeApplication

以上是关于C++:mwArray 作为 C++ 类中的变量的主要内容,如果未能解决你的问题,请参考以下文章

C++ 类 - 派生类中的构造函数声明

当我在 C++ 中派生一个类时,它是不是会创建一个基类对象并将其作为我的成员变量存储在派生类中?

const 引用字段作为 C++ 类中的只读属性

C++ 中的继承:在父子类中定义变量

C++ 类中的两个不同变量初始化。有啥不同?

C++线程更新变量问题