C++调用Matlab混合编程

时间:2022-09-22 09:12:31

C++调用Matlab混合编程

  • 简介

    C++中调用Matlab时,所用的数据类型对应为mwArray。而C中调用Matlab时,所用的数据类型是mxArray,由于mxArray的内存管理方式比较松散,没有做数据封装,故在使用时须对临时阵列和约束阵列明确,且小心地防止内存泄漏,虽然存在自动内存管理机制,但仍然要处处调用mlfAssign,较麻烦,故不建议使用。而mwArray是基于C++的,它将一切交给C++对象去做,故可以放心使用。但Matlab C++函数库为了防止频繁内存分配和释放,重写了内存分配和释放等函数。当两个mwArray对象进行赋值时,并未生成两个相同数据块,只是指针指向同一数据库,只有数据发生改变才复制完整数据。mxArray使用类似指针,而mwArray则可以直接当类使用。建议使用mwArray。mxArray最后要释放指针,但mwArray可以利用析构函数自动销毁对象。

  • mwArray使用

    1)复制数组的初始化

    double rdata[4] = {1.0, 2.0, 3.0, 4.0};
    double idata[4] = {10.0, 20.0, 30.0, 40.0};
    mwArray a(2, 2, mxDOUBLE_CLASS, mxCOMPLEX);
    a.Real().SetData(rdata, 4);
    a.Imag().SetData(idata, 4);
    对应从mwArray中获取元素
    a.Real().GetData(buffer,len);
    a.Imag().GetData(buffer,len);

    2)cell元组阵列的获取

    因mwArray索引运算符()直接返回mwArray类型,故可以直接声明通过索引获取元祖内的矩阵值。

    a={[1],[2],[1 2;3 4];[1 3;2 4],[1],[2]};
    mwArray b = a(2); //b=[1 3;2 4];
    mwArray c = a(5); //c=[1 2;3 4];

    注意:mwArray中数组为按列排列,故[1 3; 2 4]的索引号为2。

    3)mwArray成员函数

    int NumberOfDimensions()       // 返回矩阵维数
    int NumberOfElements() // 返回矩阵元素个数
    mwArray GetDimensions() // 返回一维矩阵,表示矩阵各维大小
    bool IsComplex() // 判断是否复数矩阵

    注意:使用GetData前,可先使用NumberOfElements确定元素个数,避免越界。

    4)字符串转换为mwArray

    char str[] = "inFile.mat";
    mwArray inFile(str);

    注意:inFile可以直接作为函数的输入参数进行传递。

  • mwArray类函数信息

    主要构造函数

    // 创建空的Matlab阵列,类型为mxDOUBLE_CLASS
    mwArray() : m_pa(0)
    {
    if (mclGetEmptyArray((void**)&m_pa, mxDOUBLE_CLASS) == MCLCPP_ERR)
    mwException::raise_error();
    validate();
    }
    // 创建mxID,指定类型为Matlab阵列
    mwArray(mxClassID mxID) : m_pa(0)
    {
    if (mclGetEmptyArray((void**)&m_pa, mxID) == MCLCPP_ERR)
    mwException::raise_error();
    validate();
    }
    // 创建行数为num_rows,列数为num_cols,类型为Matlab阵列,对于数值型阵列,cmplx为带创建真累是否为复数阵列
    mwArray(mwSize num_rows, mwSize num_cols, mxClassID mxID, mxComplexity cmplx = mxREAL) : m_pa(0)
    {
    if (mclGetMatrix((void**)&m_pa, num_rows, num_cols, mxID, cmplx) == MCLCPP_ERR)
    mwException::raise_error();
    validate();
    }
    // 创建任意维数的Matlab阵列,维数为num_dims,各维为dims,mxID指定阵列类型,对于数值型阵列,cmplx为带创建真累是否为复数阵列
    mwArray(mwSize num_dims, const mwSize* dims, mxClassID mxID, mxComplexity cmplx = mxREAL) : m_pa(0)
    {
    if (mclGetArray((void**)&m_pa, num_dims, dims, mxID, cmplx) == MCLCPP_ERR)
    mwException::raise_error();
    validate();
    }
    // 根据字符串str创建一个新的字符型阵列
    mwArray(const char* str) : m_pa(0)
    {
    if (mclGetString((void**)&m_pa, str) == MCLCPP_ERR)
    mwException::raise_error();
    validate();
    }
    // 创建字符型阵列,字符串由str指定
    mwArray(mwSize num_strings, const char** str) : m_pa(0)
    {
    if (mclGetCharMatrixFromStrings((void**)&m_pa, num_strings, str) == MCLCPP_ERR)
    mwException::raise_error();
    validate();
    }
    // 创建行数为num_rows,列数为num_cols结构体阵列,结构体域名为fieldnames,域名个数由num_fields指定
    mwArray(mwSize num_rows, mwSize num_cols, int num_fields, const char** fieldnames) : m_pa(0)
    {
    if (mclGetStructMatrix((void**)&m_pa, num_rows, num_cols, num_fields, fieldnames) == MCLCPP_ERR)
    mwException::raise_error();
    validate();
    }
    // 创建任意维数的结构体阵列,维数为num_dims,各维为dims,结构体域名为fieldnames,域名个数为num_fields
    mwArray(mwSize num_dims, const mwSize* dims, int num_fields, const char** fieldnames) : m_pa(0)
    {
    if (mclGetStructArray((void**)&m_pa, num_dims, dims, num_fields, fieldnames) == MCLCPP_ERR)
    mwException::raise_error();
    validate();
    }
    // 创建一个新的数值阵列,实部为re(注意类型)
    explicit mwArray(mxDouble re) : m_pa(0)
    {
    if (mclGetScalarDouble((void**)&m_pa, re, 0, mxREAL) == MCLCPP_ERR)
    mwException::raise_error();
    validate();
    }
    // 创建一个新的数值阵列,实部为re,虚部为im(注意类型)
    mwArray(mxDouble re, mxDouble im) : m_pa(0)
    {
    if (mclGetScalarDouble((void**)&m_pa, re, im, mxCOMPLEX) == MCLCPP_ERR)
    mwException::raise_error();
    validate();
    }

    主要操作函数

    // 复制操作 
    mwArray Clone() const
    {
    array_ref* p = array_ref_deep_copy(m_pa);
    if (!p)
    mwException::raise_error();
    return mwArray(p);
    }
    // 返回一个新的共享数据型mwArray阵列,此阵列与现有的mwArray阵列指向同一个数据块
    mwArraySharedCopy<mwArray> SharedCopy() const
    {
    array_ref* p = array_ref_shared_copy(m_pa);
    if (!p)
    mwException::raise_error();
    return mwArraySharedCopy<mwArray>(p);
    }
    // 将mwArray序列化一个新的阵列,新的阵列为mxUINT8_CLASS类型
    mwArray Serialize() const
    {
    array_ref* p = array_ref_serialize(m_pa);
    if (!p)
    mwException::raise_error();
    return mwArray(p);
    }
    // mwArray数据类型
    mxClassID ClassID() const
    {
    return array_ref_classID(m_pa);
    }
    // 返回mwArray阵列元素大小
    size_t ElementSize() const
    {
    return array_ref_element_size(m_pa);
    }
    // 返回阵列中元素的个数
    mwSize NumberOfElements() const
    {
    return array_ref_number_of_elements(m_pa);
    }
    // 返回阵列中非零元素个数
    mwSize NumberOfNonZeros() const
    {
    return array_ref_number_of_nonzeros(m_pa);
    }
    // 返回稀疏阵列中最大的元素的个数
    mwSize MaximumNonZeros() const
    {
    return array_ref_maximum_nonzeros(m_pa);
    }
    // 返回阵列维数
    mwSize NumberOfDimensions() const
    {
    return array_ref_number_of_dimensions(m_pa);
    }
    // 返回结构体域个数
    int NumberOfFields() const
    {
    return array_ref_number_of_fields(m_pa);
    }
    // 获取结构体域名
    mwString GetFieldName(int i)
    {
    char_buffer* p = array_ref_get_field_name(m_pa, i);
    if (!p)
    mwException::raise_error();
    return mwString(p, false);
    }
    // 获取mwArray维度
    mwArray GetDimensions() const
    {
    array_ref* p = array_ref_get_dimensions(m_pa);
    if (!p)
    mwException::raise_error();
    return mwArray(p);
    }
    // 判断是否是空阵列
    bool IsEmpty() const
    {
    return array_ref_is_empty(m_pa);
    }
    // 判断是否Sparse阵列
    bool IsSparse() const
    {
    return array_ref_is_sparse(m_pa);
    }
    // 判断是否是数值阵列
    bool IsNumeric() const
    {
    return array_ref_is_numeric(m_pa);
    }
    // 判断是否复型阵列
    bool IsComplex() const
    {
    return array_ref_is_complex(m_pa);
    }
    // 判断两个阵列是否相同
    bool Equals(const mwArray& arr) const
    {
    return array_ref_equals(m_pa, arr.m_pa);
    }
    // 比较两个mwArray结构信息
    int CompareTo(const mwArray& arr) const
    {
    return array_ref_compare_to(m_pa, arr.m_pa);
    }
    // 返回HashCode值
    int HashCode() const
    {
    return array_ref_hash_code(m_pa);
    }
    // 获取字符串信息
    mwString ToString() const
    {
    char_buffer* p = array_ref_to_string(m_pa);
    if (!p)
    mwException::raise_error();
    return mwString(p, false);
    }
    // 获取行索引
    mwArray RowIndex() const
    {
    array_ref* p = array_ref_row_index(m_pa);
    if (!p)
    mwException::raise_error();
    return mwArray(p);
    }
    // 获取列索引
    mwArray ColumnIndex() const
    {
    array_ref* p = array_ref_column_index(m_pa);
    if (!p)
    mwException::raise_error();
    return mwArray(p);
    }
    // 生成复数
    void MakeComplex()
    {
    if (array_ref_make_complex(m_pa) == MCLCPP_ERR)
    mwException::raise_error();
    }
    // 获取相关信息函数
    mwArray Get(..., ..., ...)
    {
    return GetPromoted( ..., ..., ...);
    }
    void GetData(...,...) const
    {
    ...
    }
    // 设置相关信息
    void Set(...)
    {
    ...
    }
    void SetData(..., ...)
    {
    ...
    }

    主要操作符函数

    // 相等 
    bool operator==(const mwArray& arr) const
    {
    return Equals(arr);
    }
    // 不相等
    bool operator!=(const mwArray& arr) const
    {
    return !Equals(arr);
    }
    // 小于
    bool operator<(const mwArray& arr) const
    {
    return (CompareTo(arr) < 0);
    }
    // 大于
    bool operator>(const mwArray& arr) const
    {
    return (CompareTo(arr) > 0);
    }
    // 小于等于
    bool operator<=(const mwArray& arr) const
    {
    return (CompareTo(arr) <= 0);
    }
    // 大于等于
    bool operator>=(const mwArray& arr) const
    {
    return (CompareTo(arr) >= 0);
    }
    // 输出
    friend std::ostream& operator<<(std::ostream& os, const mwArray& arr)
    {
    os << arr.ToString();
    return os;
    }
    // 赋值
    mwArray& operator=(const mwArray& arr)
    {
    if (&arr == const_cast<const mwArray*>(this)) {
    return *this;
    }
    Set(arr);
    return *this;
    }
    mwArray operator()(..., ...)
    {
    return GetPromoted(..., ...);
    }

参考文献:

[http://blog.sina.com.cn/s/blog_b3facf740101e3c7.html](http://blog.sina.com.cn/s/blog_b3facf740101e3c7.html)

http://blog.csdn.net/wishchin/article/details/37693863