C Func Void Argument Essay

Pointer Arguments

Pointer Arguments in C Functions

Many functions in external libraries pass arguments by reference. When you pass by reference, you pass a pointer to the value. In the function signature, pointer arguments have names ending in and . Although MATLAB® does not support passing by reference, you can create a MATLAB argument, called a lib.pointer object, that is compatible with a C pointer. This object is an instance of the MATLAB class.

Often, you can simply pass a MATLAB variable (passing an argument by value), even when the signature for that function declares the argument to be a pointer. There are times, however, when it is useful to pass a .

  • You want to modify the data in the input arguments.

  • You are passing large amounts of data, and you want to control when MATLAB makes copies of the data.

  • The library stores and uses the pointer so you want the MATLAB function to control the lifetime of the object.

Put String into Void Pointer

C represents characters as 8-bit integers. To use a MATLAB character array as an input argument, convert the string to the proper type and create a . For example:

The syntax creates the null-terminated string required by the C function. To read the string, and verify the pointer type, enter:

MATLAB automatically converts an argument passed by value into an argument passed by reference when the external function prototype defines the argument as a pointer. Call a function that takes a to a string as an input argument using the following syntax.

Although MATLAB converts the argument from a value to a pointer, it must be of the correct type.

str = 'string variable'; vp = libpointer('voidPtr',[int8(str) 0]);
char(vp.Value) vp.DataType
ans = string variable ans = voidPtr

Memory Allocation for External Library

In general, MATLAB passes a valid memory address each time you pass a variable to a library function. Use a object in cases where the library stores the pointer and accesses the buffer over time. In these cases, ensure that MATLAB has control over the lifetime of the buffer and prevent copies of the data from being made. The following pseudo-code is an example of asynchronous data acquisition that shows how to use a in this situation.

Suppose an external library has the following functions:

AcquireData(int points,short *buffer) IsAquisitionDone(void)

where is declared as follows:

First, create a to an array of 99 points:

BufferSize = 99; pBuffer = libpointer('int16Ptr',zeros(BufferSize,1));

Then, begin acquiring data and wait in a loop until it is done:

calllib('myLib','AcquireData,BufferSize,pbuffer) while (~calllib('myLib','IsAcquisitionDone') pause(0.1) end

The following statement reads the data in the buffer:

When the library is done with the buffer, clear the MATLAB variable:

See Also

This example shows how to write a MEX file to call a C function, , in MATLAB® using a MATLAB matrix. You can use these same C statements in a C++ application.

multiplies a 1xn matrix, , by a scalar value, , and returns the results in array, .

Create Source File

Open MATLAB Editor, create a file, and document the MEX file with the following information.

/* * arrayProduct.c - example in MATLAB External Interfaces * * Multiplies an input scalar (multiplier) * times a 1xN matrix (inMatrix) * and outputs a 1xN matrix (outMatrix) * * The calling syntax is: * * outMatrix = arrayProduct(multiplier, inMatrix) * * This is a MEX file for MATLAB. */

Add the C/C++ header file, , containing the MATLAB API function declarations.

Save the file on your MATLAB path, for example, in , and name it . The name of your MEX file is .

Create Gateway Routine

Every C program has a function. MATLAB uses the gateway routine, , as the entry point to the function. Add the following code.

/* The gateway function */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { /* variable declarations here */ /* code here */ }

This table describes the input parameters for .

ParameterDescription
Number of output (left-side) arguments, or the size of the array.
Array of output arguments.
Number of input (right-side) arguments, or the size of the array.
Array of input arguments.

Verify MEX File Input and Output Parameters

Verify the number of MEX file input and output arguments using the and arguments.

To check for two input arguments, and , use this code.

if(nrhs != 2) { mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nrhs", "Two inputs required."); }

Use this code to check for one output argument, the product .

if(nlhs != 1) { mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nlhs", "One output required."); }

Verify the argument types using the and arguments. This code validates that , represented by , is a scalar.

/* make sure the first input argument is scalar */ if( !mxIsDouble(prhs[0]) || mxIsComplex(prhs[0]) || mxGetNumberOfElements(prhs[0]) != 1 ) { mexErrMsgIdAndTxt("MyToolbox:arrayProduct:notScalar", "Input multiplier must be a scalar."); }

This code validates that , represented by , is type .

if( !mxIsDouble(prhs[1]) || mxIsComplex(prhs[1])) { mexErrMsgIdAndTxt("MyToolbox:arrayProduct:notDouble", "Input matrix must be type double."); }

Validate that is a row vector.

/* check that number of rows in second input argument is 1 */ if(mxGetM(prhs[1]) != 1) { mexErrMsgIdAndTxt("MyToolbox:arrayProduct:notRowVector", "Input must be a row vector."); }

Create Computational Routine

Add the code. This function is your computational routine, the source code that performs the functionality you want to use in MATLAB.

void arrayProduct(double x, double *y, double *z, int n) { int i; for (i=0; i<n; i++) { z[i] = x * y[i]; } }

A computational routine is optional. Alternatively, you can place the code within the function block.

Write Code for Cross-Platform Flexibility

MATLAB provides a preprocessor macro, , that represents size values for integers, based on the platform. The computational routine declares the size of the array as . Replace the declaration for variables and with .

void arrayProduct(double x, double *y, double *z, mwSize n) { mwSize i; for (i=0; i<n; i++) { z[i] = x * y[i]; } }

Declare Variables for Computational Routine

Put the following variable declarations in .

  • Declare variables for the input arguments.

    double multiplier; /* input scalar */ double *inMatrix; /* 1xN input matrix */
  • Declare for the size of the input matrix.

    mwSize ncols; /* size of matrix */
  • Declare the output argument, .

    double *outMatrix; /* output matrix */

Later you assign the arguments to these variables.

Read Input Data

To read the scalar input, use the function.

/* get the value of the scalar input */ multiplier = mxGetScalar(prhs[0]);

Use the function to point to the input matrix data.

/* create a pointer to the real data in the input matrix */ inMatrix = mxGetPr(prhs[1]);

Use the function to get the size of the matrix.

/* get dimensions of the input matrix */ ncols = mxGetN(prhs[1]);

Prepare Output Data

To create the output argument, , use the function.

/* create the output matrix */ plhs[0] = mxCreateDoubleMatrix(1,ncols,mxREAL);

Use the function to assign the argument to

/* get a pointer to the real data in the output matrix */ outMatrix = mxGetPr(plhs[0]);

Perform Calculation

Pass the arguments to .

/* call the computational routine */ arrayProduct(multiplier,inMatrix,outMatrix,ncols);

View Complete Source File

Compare your source file with , located in . Open the file in the editor.

Build Binary MEX File

At the MATLAB command prompt, build the binary MEX file.

Test the MEX File

Validate MEX File Input Arguments

It is good practice to validate the type of a MATLAB variable before calling a MEX file. To test the input variable, , and convert it to , if necessary, use this code.

s = 5; A = [1.5, 2, 9]; B = arrayProduct(s,A)
B = 7.5000 10.0000 45.0000
A = [1.5, 2, 9]; inputArg = int16(A); if ~strcmp(class(inputArg),'double') inputArg = double(inputArg); end B = arrayProduct(s,inputArg)

See Also

| | | | |

Related Examples

More About

0 thoughts on “C Func Void Argument Essay

Leave a Reply

Your email address will not be published. Required fields are marked *