我最终通过带有注释的示例意识到了这一点。在此,我将示例实现代码张贴在此供其他有兴趣的人参考。
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "mex.h"
#include <matrix.h>
#include <Eigen/Dense>
#include "Eigen/Eigen"
#include "Eigen/LU"
#include "Eigen/SVD"
using namespace Eigen;
using namespace std;
#include "mpir.h"
#include "mpreal.h"
#include <cstring>
#include <string>
using namespace mpfr;
struct mystruct
{
char *a;
double *b;
double *c;
double *d;
};
void printme( char *a, double *b, double *c, double *d )
{
mexPrintf(a);
mexPrintf( "\n a = %s,\tb = %f,\tc = %f,\td = %f\n", a, b[0], c[0], d[0] );
mexPrintf( "a = %s,\tb = %f,\tc = %f,\td = %f\n", a, b[99], c[99], d[99] );
}
void mexFunction(
int nlhs,
mxArray *plhs[],
int nrhs,
const mxArray *prhs[]
)
{
const int digits = 256;
mpreal::set_default_prec(mpfr::digits2bits(digits));
const mpreal pi = mpfr::const_pi();
const int n = 5;
typedef Matrix<mpreal,Dynamic,Dynamic> MatrixXmp;
typedef Matrix<mpreal,Dynamic,1> VectorXmp;
MatrixXmp A = MatrixXmp::Random(n,n);
VectorXmp b = VectorXmp::Random(n);
VectorXmp x = A.lu().solve(b);
VectorXmp residue0 = A *x -b;
mpreal residue = residue0.norm();
if(nlhs>=1){
const char *fieldnames[] = {"a", "b" , "c" , "d"};
int T = 100;
struct mystruct X;
plhs[0] = mxCreateStructMatrix(1 , 1 , 4 , fieldnames);
string str2= pi.toString();
mxSetFieldByNumber(plhs[0] ,0 , 0 , mxCreateString(str2.c_str()));
for(int i = 1 ; i < 4 ; i++){
mxArray *data = mxCreateNumericMatrix(T, 1 , mxDOUBLE_CLASS,mxREAL);
for(int j = 0; j < T; j++ ) {
*(mxGetPr(data) + j) = (i * T) + j;
}
mxSetFieldByNumber(plhs[0] ,0 , i , data);
}
int strlenn= mxGetN(mxGetFieldByNumber( plhs[0], 0, 0 ))+1;
X.a = (char*)mxCalloc(strlenn,sizeof(char));
printf("\n X.a before being allocated a string is %s ; size of X.a is %d \n",X.a,sizeof(X.a));
mxGetString(mxGetFieldByNumber( plhs[0], 0, 0 ),X.a ,strlenn);
printf("The strlen of X.a is %d, size of X.a is %d, mxGetN+1 is %d , sizeof char is %d \n",strlen(X.a),sizeof(X.a),strlenn,sizeof(char));
X.b = mxGetPr( mxGetFieldByNumber( plhs[0], 0, 1 ) );
X.c = mxGetPr( mxGetFieldByNumber( plhs[0], 0, 2 ) );
X.d = mxGetPr( mxGetFieldByNumber( plhs[0], 0, 3 ) );
printme(X.a, X.b, X.c, X.d);
}
if (nlhs>=2&&nrhs<1){
double *two2three;
plhs[1]= mxCreateDoubleMatrix(n,n, mxREAL);
two2three= mxGetPr(plhs[1]);
for (int i=0;i<n;i++)
for(int j=0; j<n; j++){
two2three[i+j*n]=A(i, j).toDouble();
}
}
if (nlhs>=2 && nrhs>=1){
mwSize ndims[] ={5,5} ;
int nsubs=2;
mwIndex subs[2];
plhs[1]= mxCreateCellArray(2, ndims);
for (int i=0;i<n;i++)
for(int j=0; j<n; j++){
subs[0]=i;subs[1]=j;
int index = mxCalcSingleSubscript(plhs[1], nsubs, subs);
mxSetCell(plhs[1],index,mxCreateString(_strdup(A(i, j).toString().c_str())));
}
}
if (nlhs>=3 && nrhs<1){
double *three2two;
plhs[2]= mxCreateDoubleMatrix(n,1, mxREAL);
three2two = mxGetPr(plhs[2]);
for (int i=0;i<n;i++)
three2two[i]=b(i).toDouble();
}
if (nlhs>=3&&nrhs>=1){
plhs[2]=mxCreateCellMatrix(n, 1);
for (int i = 0; i < n; i++) {
mxSetCell(plhs[2],i,mxCreateString(_strdup(b(i).toString().c_str())));
}
}
if (nlhs>=4&& nrhs<1){
double *solution;
plhs[3]= mxCreateDoubleMatrix(n,1, mxREAL);
solution = mxGetPr(plhs[3]);
for (int i=0;i<n;i++)
solution[i]= x(i).toDouble();
}
if (nlhs>=4 && nrhs>=1){
plhs[3]=mxCreateCellMatrix(n, 1);
for (int i = 0; i < n; i++) {
mxSetCell(plhs[3],i,mxCreateString(_strdup(x(i).toString().c_str())));
}
}
if (nlhs>=5)
plhs[4] = mxCreateString(residue.toString().c_str());
if (nlhs>=6){
plhs[5]=mxCreateCellMatrix(n, 1);
for (int i = 0; i < n; i++) {
mxSetCell(plhs[5],i,mxCreateString(_strdup(residue0(i).toString().c_str())));
}
}
if (nlhs>=7&&nrhs>=1){
double *xconversion = (double *) mxGetPr(prhs[0]);
mpreal yconversion =xconversion[0];
mexPrintf("\n The input argument in double is %lf \n mpreal double is %lf string is %s; ",xconversion[0],yconversion.toDouble(),yconversion.toString().c_str());
plhs[6] = mxCreateString(yconversion.toString().c_str());
}
if (nlhs>=8&&nrhs>=2){
if (!mxIsCell(prhs[1])){
mexPrintf("\n 2nd input argument must be cell matrix.\n");
}
mwIndex subs8[] ={0};
mxArray *strtmp;
int cameraNum = mxGetNumberOfElements(prhs[1]);
mwIndex dims[]={3,4,cameraNum};
plhs[7] = mxCreateNumericArray(3,dims,mxDOUBLE_CLASS,mxREAL);
MatrixXmp eigenM(3,4);
mpreal tempdbl;
for (int i=0;i<cameraNum;i++){
*subs8 = i;
strtmp = mxGetCell(prhs[1],mxCalcSingleSubscript(prhs[1], 1, subs8));
int nrows = mxGetM(strtmp);
int ncols = mxGetN(strtmp);
mexPrintf("\n No. %d camera matrix is: \n",i+1);
for (int m=0; m<3;m++){
for(int n=0;n<4;n++){
tempdbl = ((double*)mxGetPr(strtmp))[m+n*nrows];
((double*)mxGetPr(plhs[7]))[i*nrows*ncols+m+n*nrows]= tempdbl.toDouble();
if(i==cameraNum-1)
eigenM(m,n) = tempdbl;
mexPrintf("%lf\t",((double*)mxGetPr(strtmp))[m+n*nrows]);
}
mexPrintf("\n");
}
}
mexPrintf("\n");
for (int i=0;i<4;i++){
mexPrintf("\n Column No. %d :\n",i+1);
for (int j=0; j<3;j++){
mexPrintf(" %s \n",eigenM(j,i).toString().c_str());
}
}
std::ostringstream strss;
strss << ((double*)mxGetPr(strtmp))[2+3*3];
std::string strnum = strss.str();
mpreal mprrealnum=((double*)mxGetPr(strtmp))[2+3*3];
char *charnum =new char[strnum.size()+1];
charnum[strnum.size()]=0;
memcpy(charnum,strnum.c_str(),strnum.size());
mexPrintf("\n The converted double string is %s with size %d \n",charnum,strnum.size());
mexPrintf(" The mpreal based conversion is %s \n",mprrealnum.toString().c_str());
}
return;
}
cat(3, p {:})
有什么问题吗? - Edric