Array of int at the output of a mex file - matlab

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]) );
}

Related

Matlab S-Function crashing when set to dynamically sized

i have following problem. I have created a S-Function which should read a matrix from a text file, where the output size of the output port is not known and therefore set as dynamically sized. Matlab is then crashing. When setting for fixed size, there is no problem. I hope someone could help me out
#define S_FUNCTION_NAME Data_Input
#define S_FUNCTION_LEVEL 2
/*---- Define size of input ports ---------------------------------------------------*/
#define OUTPUTSIZE 50
/*-----------------------------------------------------------------------------------*/
#include <stdio.h>
#include "simstruc.h"
int_T in;
/*---- Define data types ------------------------------------------------------------*/
typedef struct SBufferData
{
real32_T data[50];
int32_T number;
} SBuffer;
/*==== mdlCheckParameters ===========================================================*/
#undef MDL_CHECK_PARAMETERS /* Change to #undef to remove function */
#if defined(MDL_CHECK_PARAMETERS) && defined(MATLAB_MEX_FILE)
static void mdlCheckParameters(SimStruct *S)
{
}
#endif /* MDL_CHECK_PARAMETERS */
/*===================================================================================*/
/*=== mdlInitializeSizes ============================================================*/
static void mdlInitializeSizes(SimStruct *S)
{
ssSetNumSFcnParams(S,1); /* number of expected parameters */
ssSetSFcnParamTunable(S, 0, 0); /* sets parameter 1 to be non-tunable */
ssSetSFcnParamTunable(S, 1, 0); /* sets parameter 2 to be non-tunable */
ssSetNumContStates(S,0); /* number of continuous states */
ssSetNumDiscStates(S,0); /* number of discrete states */
ssSetNumInputPorts(S,0); /* number of input ports */
ssSetNumOutputPorts(S,1); /* number of output ports */
ssSetOutputPortWidth(S,0,DYNAMICALLY_SIZED); /* first output port width */
ssSetOutputPortDataType(S,0,SS_SINGLE); /* first output port data type */
ssSetNumSampleTimes(S,0); /* number of sample times */
ssSetNumRWork(S,0); /* number real work vector elements */
ssSetNumIWork(S,0); /* number int_T work vector elements */
ssSetNumPWork(S,1); /* number ptr work vector elements */
ssSetNumModes(S,0); /* number mode work vector elements */
ssSetNumNonsampledZCs(S,0); /* number of nonsampled zero crossing */
if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
return; /* Parameter mismatch reported by the Simulink engine*/
}
}
/*===================================================================================*/
/*==== mdlInitializeSampleTimes =====================================================*/
static void mdlInitializeSampleTimes(SimStruct *S)
{
real_T dSampleTime=(mxGetPr(ssGetSFcnParam(S,0))[0]);
ssSetSampleTime(S, 0, dSampleTime);
ssSetOffsetTime(S, 0, 0.0);
}
/*===================================================================================*/
/*==== mdlStart =====================================================================*/
#define MDL_START /* Change to #undef to remove function */
#if defined(MDL_START)
static void mdlStart(SimStruct *S)
{
FILE *fp;
int_T i, index=0;
SBuffer *buffer;
float temp;
/*---- Retrieve pointer to pointers work vector -------------------------------------*/
void **PWork = ssGetPWork(S);
buffer = (SBuffer *)malloc(OUTPUTSIZE * sizeof(SBuffer));
PWork[0] = (void *)buffer;
/*---- Read from text-file ----------------------------------------------------------*/
fp = fopen("myfile.txt", "r");
while(feof(fp)==0)
{
fscanf(fp,"%f",&temp);
buffer -> data[index] = temp;
index++;
}
buffer -> number = (int32_T) index;
fclose(fp);
}
#endif /* MDL_START */
/*===================================================================================*/
/*==== mdlOutputs ===================================================================*/
static void mdlOutputs(SimStruct *S, int_T tid)
{
/*---- Get input ports --------------------------------------------------------------*/
real_T *y1=(real_T *)ssGetOutputPortSignal(S,0);
int_T i;
SBuffer *buffer;
/*---- Retrieve pointer to pointers work vector -------------------------------------*/
void **PWork = ssGetPWork(S);
buffer = PWork[0];
for (i = 0; i < buffer->number; i++)
{
y1[i] = buffer->data[i];
}
}
/*===================================================================================*/
/*==== mdlTerminate =================================================================*/
static void mdlTerminate(SimStruct *S)
{
SBuffer *buffer;
/*---- Retrieve pointer to pointers work vector -------------------------------------*/
void **PWork = ssGetPWork(S);
buffer = PWork[0];
/*---- Deallocate structure 'info' and 'buffer' -------------------------------------*/
free(buffer);
}
/*===================================================================================*/
/*==== Required S-function trailer ==================================================*/
#ifdef MATLAB_MEX_FILE /* Is this file being compiled as a MEX-file? */
#include "simulink.c" /* MEX-file interface mechanism */
#else
#include "cg_sfun.h" /* Code generation registration function */
#endif
/*===================================================================================*/

Mex files: mxCreateXXX only inside main mexFunction()?

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!

X11 Equivalent of gdk_pixbuf_add_alpha

In x11 I have obtained the binary blob by using XGetImage.
In GDK we have this function that adds alpha of 255 to the Pixbuf: https://developer.gnome.org/gdk-pixbuf/stable/gdk-pixbuf-Utilities.html#gdk-pixbuf-add-alpha
I was wondering if there is a convenient function like this in X11.
So I have a struct like this:
typedef struct _XImage {
int width, height; /* size of image */
int xoffset; /* number of pixels offset in X direction */
int format; /* XYBitmap, XYPixmap, ZPixmap */
char *data; /* pointer to image data */
int byte_order; /* data byte order, LSBFirst, MSBFirst */
int bitmap_unit; /* quant. of scanline 8, 16, 32 */
int bitmap_bit_order; /* LSBFirst, MSBFirst */
int bitmap_pad; /* 8, 16, 32 either XY or ZPixmap */
int depth; /* depth of image */
int bytes_per_line; /* accelerator to next scanline */
int bits_per_pixel; /* bits per pixel (ZPixmap) */
unsigned long red_mask; /* bits in z arrangement */
unsigned long green_mask;
unsigned long blue_mask;
XPointer obdata; /* hook for the object routines to hang on */
struct funcs { /* image manipulation routines */
struct _XImage *(*create_image)();
int (*destroy_image)();
unsigned long (*get_pixel)();
int (*put_pixel)();
struct _XImage *(*sub_image)();
int (*add_pixel)();
} f;
} XImage;
And in the ximage.data field I have RGB binary data. Im helping a friend and I need to make that RGBA binary data.
Thanks
Unfortually there is no such abstraction as in GDK.
You have to do it manually by iterating on the *char data member.

MATLAB input struct with unsigned char into MEX file

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

Mex file gives segmentation fault only on second use

The following code compiles successfully and returns the correct results when called the first time. Making the same call a second time, I get a segmentation fault error.
//% function TF = InWindow(Date,WindowStartDates,WindowEndDates,EndHint)
//% INWINDOW returns true for window that contains Date. All inputs must be
//% uint32 and WindowEndDates must be sorted.
//% EndHint is an optional input that specifies the row number to start
//% searching from.
#include "mex.h"
#include "matrix.h"
#include "math.h"
void CalculationRoutine(mxLogical *ismember, uint32_T *Date, uint32_T *WindowStartDates, uint32_T *WindowEndDates, unsigned int *StartIndex, int NumObs) {
mwIndex Counter;
// Find the first window that ends on or after the date.
for (Counter = (mwIndex) *StartIndex; Counter < NumObs; Counter++) {
if (*Date <= *(WindowEndDates+Counter)) {
break;
}
}
*StartIndex = (unsigned int) Counter;
// Now flag every observation within the window. Remember that WindowStartDates
// is not necessarily sorted (but WindowEndDates is).
for (Counter = (mwIndex) *StartIndex; Counter < NumObs; Counter++) {
if (*Date >= *(WindowStartDates+Counter)) {
*(ismember+Counter) = true;
}
}
}
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) {
mxArray *ismember;
unsigned int *StartIndex;
//Input Checking.
if (nrhs == 3) {
// Default Hint to first entry.
mexPrintf("SI Starts OK.\n");
*StartIndex = 1;
mexPrintf("SI Ends OK.\n");
} else if (nrhs == 4) {
if (!mxIsUint32(prhs[3])) {
mexErrMsgTxt("EndHint must be uint32.");
}
StartIndex = mxGetData(prhs[3]);
} else {
mexErrMsgTxt("Must provide three or four input arguments.");
}
// Convert the hint to base-zero indexing.
*StartIndex = *StartIndex - 1;
// Check the inputs for the window range.
if (!mxIsUint32(prhs[0])) {
mexErrMsgTxt("DatesList must be uint32.");
}
if (!mxIsUint32(prhs[1])) {
mexErrMsgTxt("WindowStartsDates must be uint32.");
}
if (!mxIsUint32(prhs[2])) {
mexErrMsgTxt("WindowEndsDates must be uint32.");
}
if (mxGetM(prhs[1]) != mxGetM(prhs[2])) {
mexErrMsgTxt("WindowStartDates must be the same length as WindowEndDates.");
}
// Prepare the output array.
ismember = mxCreateLogicalArray(mxGetNumberOfDimensions(prhs[1]), mxGetDimensions(prhs[1]));
CalculationRoutine(mxGetLogicals(ismember),mxGetData(prhs[0]),
mxGetData(prhs[1]), mxGetData(prhs[2]), StartIndex, (int) mxGetM(prhs[1]));
plhs[0] = ismember;
}
I call it with:
>>InWindow(uint32(5),uint32((1:6)'),uint32((3:8)'))
The code reaches the line between the two mexPrintf calls before the segmentation fault (ie the first call prints, but not the second).
I am on Matlab 2007a (yes, I know), Win7 64bit and VS 2008.
You need to initialize the pointer StartIndex - you're "lucky" that it works the first time, since it is not pointing to a defined memory location. Why not do something more like:
unsigned int StartIndex;
// and either:
StartIndex = 1;
// or:
StartIndex = * (static_cast< unsigned int * >( mxGetData(prhs[3]) ) );