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