I'm trying to plot data out from a MEX file (C language). To do this fast, I would like to use what corresponds to the following Matlab code:
figure; imagehandle = imagesc(rand(500));
new_CData = rand(500);
set(newCData,imagehandle);
For this, the command mexSet() should be working. Ideally, I want something like this
mex plotX.c
figure; imagehandle = imagesc(rand(500));
A = rand(500);
plotX(A,imagehandle)
with a mex-Function plotX. Here is my tryout:
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
double *x, imagehandle;
(void) plhs;
x = mxGetPr(prhs[0]);
imagehandle = mxGetScalar(prhs[1]);
mexSet(imagehandle,"Cdata",x);
}
This can be compiled, but I get the following error: "Error using plotX. Numeric or logical matrix required for image CData".
What am I doing wrong?
Solution:
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
double *x, imagehandle;
(void) plhs;
imagehandle = mxGetScalar(prhs[1]);
mexSet(imagehandle,"Cdata",prhs[0]);
}
I found this out when I used a different compiler which gave me the following error: " note: expected ‘struct mxArray *’ but argument is of type ‘double *’". And prhs[] is already a mxArray, so easy to solve ...
Related
Hello StackOverflow community
I have a very basic mexFunction implemented in Visual Studio 2013. I can compile a empty mexFunction as follows, and when I test it in MATLAB, it works perfectly:
#include "mex.h"
void mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
{
}
However, when I enter any function, the compilation is still successful but when I try to run in MATLAB, MATLAB crashes.
#include "mex.h"
void mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
{
const char* message = "Hello World";
mexPrintf(message);
}
This is as basic an example as humanly possible, and it causes MATLAB to crash. It does not use any of the inputs I provide.I have tried 0 inputs to 3 inputs:
cfg.i = 1;
cfg.o = 2;
cfg.p = 3;
mcx(cfg);
mcx is the name of the mex function compiled by visual studio. I clear my entire folder before re-compiling the mexFunction. Any help on this problem will be very helpful.
Compilation of this code is succesful but crashes MATLAB as well:
#include "mex.h"
void mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
{
mexPrintf("test");
}
I have a very basic mex file example here:
#include "mex.h"
#include "matrix.h"
void createStructureArray(mxArray* main_array)
{
const char* Title[] = { "first", "second" };
main_array = mxCreateStructMatrix(1,1, 2, Title);
}
void mexFunction(mwSize nlhs, mxArray *plhs[], mwSize nrhs,
const mxArray *prhs[])
{
double* x = mxGetPr(prhs[0]);
if (*x < 1.0)
{
//This works
const char* Title[] = { "first", "second" };
plhs[0] = mxCreateStructMatrix(1,1, 2, Title);
}
else
{
//This does not
createStructureArray(plhs[0]);
}
}
This function should always return a struct with the elements first and second. No matter the input, I expect the same output. However with an input parameter < 1, everything works as expected, but > 1 I get an error message:
>> a = easy_example(0.0)
a =
first: []
second: []
>> a = easy_example(2.0)
One or more output arguments not assigned during call to "easy_example".
Thus, can I not call the mxCreateStructMatrix function outside mexFunction, or did I do something wrong when passing the pointers?
You don't have a problem with mex but with pointers!
Try to change your function to:
void createStructureArray(mxArray** main_array)
{
const char* Title[] = { "first", "second" };
*main_array = mxCreateStructMatrix(1,1, 2, Title);
}
and the function call to
createStructureArray(&plhs[0]);
Your problem is that plhs[0] is a mxArray, but in order to return it, you need to pass the pointer to that mxArray!
I tried to input this struct from MATLAB into my MEX file: struct('speed',{100.3},'nr',{55.4},'on',{54}), but the last value which is defined in my MEX file as unsigned char reads out as zero before calling my C function? The two double values works like intended.
struct post_TAG
{
double speed;
double nr;
unsigned char on;
};
const char *keys[] = { "speed", "nr", "on" };
void testmex(post_TAG *post)
{
...
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[])
{
post_TAG post;
int numFields, i;
const char *fnames[3];
mxArray *tmp;
double *a,*b;
unsigned char *c;
numFields=mxGetNumberOfFields(prhs[0]);
for(i=0;i<numFields;i++)
fnames[i] = mxGetFieldNameByNumber(prhs[0],i);
tmp = mxGetField(prhs[0],0,fnames[0]);
a=(double*)mxGetData(tmp);
tmp = mxGetField(prhs[0],0,fnames[1]);
b=(double*)mxGetData(tmp);
tmp = mxGetField(prhs[0],0,fnames[2]);
c=(unsigned char*)mxGetData(tmp);
mexPrintf("POST0, speed=%f, nr=%f, on=%u\n",*a,*b,*c);
post.speed = *a;
post.nr = *b;
post.on = *c;
testmex(&post);
}
In a struct defined as struct('speed',{100.3},'nr',{55.4},'on',{54}), the field on is a double. Pass as a uint8 from MATLAB:
struct('speed',{100.3},'nr',{55.4},...
'on',{uint8(54)}),
Any numeric value without a specified type in MATLAB is a double.
Also note that for reading a scalar value, the problem is simplified somewhat by mxGetScalar. It will return one double value for any underlying data type.
unsigned char s = (unsigned char) mxGetScalar(...); // cast a double to unsigned char
Inspired from this post, I am interested to pass std::strings into the cell array. However, the mxDuplicateArray accepts mxArray format variables. I have tried to transform the std::string to mxArray with mxGetString but without success.
Could you please make a suggestion on this?
Thanks!
void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[])
{
std::string str ("Hellooo");
const char *cstr = str.c_str();
mwSize len = 10;
mxArray *mxarr = mxCreateCellMatrix(len, 1);
mxArray *mxstr = mxCreateString("");
mxGetString(mxstr, (char*) cstr, str.length());
for(mwIndex i=0; i<len; i++) {
// I simply replaced the call to mxDuplicateArray here
mxSetCell(mxarr, i, mxDuplicateArray(mxstr));
}
mxDestroyArray(mxstr);
plhs[0] = mxarr;
}
You could also cut out the call to mxDuplicateArray (and mxDestroyArray).
#include "mex.h"
#include <string>
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
std::string str("Hellooo");
const char *cstr = str.c_str();
mwSize len = 10;
mxArray *mxarr = mxCreateCellMatrix(len, 1);
for (mwIndex i=0; i<len; i++) {
mxSetCell(mxarr, i, mxCreateString(cstr));
}
plhs[0] = mxarr;
}
Untested...
From the docs on mxGetString:
Call mxGetString to copy the character data of a string mxArray
What you want, is the opposite: create an mxArray from a c-style string. For that you can use
mxCreateString directly. It seems to tried to use it to create an empty string at first. This should work:
void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[])
{
std::string str ("Hellooo");
const char *cstr = str.c_str();
mwSize len = 10;
mxArray *mxarr = mxCreateCellMatrix(len, 1);
mxArray *mxstr = mxCreateString(cstr);
// no need for this line
// mxGetString(mxstr, (char*) cstr, str.length());
for(mwIndex i=0; i<len; i++) {
// I simply replaced the call to mxDuplicateArray here
mxSetCell(mxarr, i, mxDuplicateArray(mxstr));
}
mxDestroyArray(mxstr);
plhs[0] = mxarr;
}
I am trying to create a mex function whose entry is an integer and whose output is an array of integer.
So the function looks like: int *myFunction(unsigned int N).
In the mexFunction, I declare a variable *variab of type int and then
N = mxGetScalar(prhs[0]);
/* assign a pointer to the output */
siz= 2*ceil(log(1.0*N)/log(2.0)-0.5)+1;
plhs[0] = mxCreateDoubleMatrix(1,siz, mxREAL);
vari = (int*) mxGetPr(plhs[0]); */
/* Call the subroutine. */
vari = myFunction(N);
mexPrintf("The first value is %d\n", vari[0]);
The thing is the first value is the correct one (and the other ones were checked and were correct as well) but when I call the routine mxFunction(16), I get only 0's as output.
I guess it is because my output is an array of int but I don't know how to solve the problem. Any hint?
Cheers.
Matlab deals with doubles by default. You can easily cast them in your mex function like the following example based on your code snippet. I have made a myFunction that performs a demo algorithm. Rather than return a data type, I make it a void function and pass it a pointer to the output so that it can populate it . . .
/*************************************************************************/
/* Header(s) */
/*************************************************************************/
#include "mex.h"
#include "math.h"
/*************************************************************************/
/*the fabled myFunction */
/*************************************************************************/
void myFunction(unsigned int N, unsigned int siz, double* output)
{
int sign = 1;
for(int ii=0; ii<siz; ++ii)
{
output[ii] = (double)(ii * sign + N);
sign *= -1;
}
}
/*************************************************************************/
/* Gateway function and error checking */
/*************************************************************************/
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
/* variable declarations */
unsigned int siz;
double N;
/* check the number of input and output parameters */
if(nrhs!=1)
mexErrMsgTxt("One input arg expected");
if(nlhs > 1)
mexErrMsgTxt("Too many outputs");
N = mxGetScalar(prhs[0]);
/* assign a pointer to the output */
siz= 2*ceil(log(1.0*N)/log(2.0)-0.5)+1;
plhs[0] = mxCreateDoubleMatrix(1,siz, mxREAL);
myFunction(N, siz, mxGetPr( plhs[0]) );
}