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