External Interfaces/API |
Passing Strings
Any MATLAB data type can be passed to and from MEX-files. For example, this C code accepts a string and returns the characters in reverse order.
/* * ============================================================= * revord.c * Example for illustrating how to copy the string data from * MATLAB to a C-style string and back again. * * Takes a string and returns a string in reverse order. * * This is a MEX-file for MATLAB. * Copyright (c) 1984-2000 The MathWorks, Inc. * ============================================================ */ /* $Revision: 1.9 $ */ #include "mex.h" void revord(char *input_buf, int buflen, char *output_buf) { int i; /* Reverse the order of the input string. */ for (i = 0; i < buflen-1; i++) *(output_buf+i) = *(input_buf+buflen-i-2); }
In this example, the API function mxCalloc
replaces calloc
, the standard C function for dynamic memory allocation. mxCalloc
allocates dynamic memory using the MATLAB memory manager and initializes it to zero. You must use mxCalloc
in any situation where C would require the use of calloc
. The same is true for mxMalloc
and mxRealloc
; use mxMalloc
in any situation where C would require the use of malloc
and use mxRealloc
where C would require realloc
.
Below is the gateway routine that calls the C computational routine revord
.
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { char *input_buf, *output_buf; int buflen,status; /* Check for proper number of arguments. */ if (nrhs != 1) mexErrMsgTxt("One input required."); else if (nlhs > 1) mexErrMsgTxt("Too many output arguments."); /* Input must be a string. */ if (mxIsChar(prhs[0]) != 1) mexErrMsgTxt("Input must be a string."); /* Input must be a row vector. */ if (mxGetM(prhs[0]) != 1) mexErrMsgTxt("Input must be a row vector."); /* Get the length of the input string. */ buflen = (mxGetM(prhs[0]) * mxGetN(prhs[0])) + 1; /* Allocate memory for input and output strings. */ input_buf = mxCalloc(buflen, sizeof(char)); output_buf = mxCalloc(buflen, sizeof(char)); /* Copy the string data from prhs[0] into a C string * input_buf. If the string array contains several rows, * they are copied, one column at a time, into one long * string array. */ status = mxGetString(prhs[0], input_buf, buflen); if (status != 0) mexWarnMsgTxt("Not enough space. String is truncated."); /* Call the C subroutine. */ revord(input_buf, buflen, output_buf); /* Set C-style string output_buf to MATLAB mexFunction output*/ plhs[0] = mxCreateString(output_buf); return; }
The gateway routine allocates memory for the input and output strings. Since these are C strings, they need to be one greater than the number of elements in the MATLAB string. Next the MATLAB string is copied to the input string. Both the input and output strings are passed to the computational subroutine (revord
), which loads the output in reverse order. Note that the output buffer is a valid null-terminated C string because mxCalloc
initializes the memory to 0. The API function mxCreateString
then creates a MATLAB string from the C string, output_buf
. Finally, plhs[0]
, the left-hand side return argument to MATLAB, is set to the MATLAB array you just created.
By isolating variables of type mxArray
from the computational subroutine, you can avoid having to make significant changes to your original C code.
A First Example -- Passing a Scalar | Passing Two or More Inputs or Outputs |