| Contents | Index |
In most cases, you can pass arguments to an external function by value, even when the prototype for that function declares the argument to be a pointer. The calllib function uses the header file to determine how to pass the function arguments.
There are times, however, when it is useful to pass MATLAB arguments by reference, similar to using a C pointer:
You want to modify the data in the input arguments.
You are passing large amounts of data, and you don't want to make copies of the data.
The library stores and uses the pointer for a period of time so you want the MATLAB function to control the lifetime of the libpointer object.
In these cases, you use the libpointer function to construct a libpointer object of a specified type. A libpointer is an instance of a MATLAB lib.pointer class. The properties of this class are Value and DataType. The methods are:
Methods for class lib.pointer: disp plus setdatatype isNull reshape
For information about using the setdatatype method, see Reading a libpointer Object and the example in Reading Function Return Values. For an example using the plus operator, see Creating a Pointer by Offsetting from an Existing libpointer. For an example using the reshape method, see Guidelines for Passing Arguments.
When working with structures, use the libstruct function, as described in Working with Structures.
To construct a pointer, use the function libpointer with this syntax:
p = libpointer('type', 'value')For example, you want to create a pointer, pv, to a value of type int16. In this case, the type of the pointer is the data type (int16) suffixed by the letters Ptr:
pv = libpointer('int16Ptr', 485);To read the properties of the variable pv, type:
get(pv)
MATLAB displays:
Value: 485
DataType: 'int16Ptr'When a library function returns a libpointer object, you must initialize its type and size using the setdatatype method. The function signature for setdatatype is:
setdatatype(handle, string, double)
where handle is the object's handle, string is the type, and double is the size. For an example, see Reading Function Return Values.
The following example illustrates how to construct and pass a pointer, and how to interpret the output. It uses the multDoubleRef function in the shrlibsample library, which multiplies the input by 5. The input is a pointer to a double, and it returns a pointer to a double. The C code for the function is:
EXPORTED_FUNCTION double *multDoubleRef(double *x)
{
*x *= 5;
return x;
}Construct a libpointer object, xp, to point to the input data, x.
x = 15;
xp = libpointer('doublePtr', x);
Verify the contents of xp:
get(xp)
MATLAB displays:
Value: 15
DataType: 'doublePtr'Now call the function and check the results:
calllib('shrlibsample', 'multDoubleRef', xp);
xp.Value
MATLAB displays:
ans = 75
The object xp is a handle object. All copies of this handle refer to the same underlying object and any operations you perform on a handle object affect all copies of that object. However, object xp is not a C language pointer. Although it points to x, it does not contain the address of x. The function modifies the Value property of xp but does not modify the value in the underlying objectx. The original value of x is unchanged. Type:
x
MATLAB displays:
x =
15In the previous example, the result of the function called from MATLAB could be obtained by examining the modified input pointer. But this function also returns data in its output arguments that may be useful.
To see the MATLAB prototype for multDoubleRef, type:
libfunctions shrlibsample -full
Look for the entry:
[lib.pointer, doublePtr] multDoubleRef(doublePtr)
The function returns two outputs — a libpointer object and the Value property of the input argument:
Run the example again:
x = 15;
xp = libpointer('doublePtr', x);
Check the output values:
[xobj, xval] = calllib('shrlibsample', 'multDoubleRef', xp)
MATLAB displays:
xobj =
lib.pointer
xval =
75Like the input argument xp, xobj is also a libpointer object. You can examine this output, but first you need to initialize its type and size because the function does not define these properties. Use the setdatatype function defined by class lib.pointer to set the data type to doublePtr and the size to 1-by-1. Once initialized, you can examine outputs by typing:
setdatatype(xobj, 'doublePtr', 1, 1) get(xobj)
MATLAB displays:
ans =
Value: 75
DataType: 'doublePtr'The second output of multDoubleRef, xval, is a copy of the Value property of input xp.
You can use the plus operator (+) to create a new pointer that is offset from an existing pointer by a scalar numeric value. For example, suppose you create a libpointer to the vector x:
x = 1:10;
xp = libpointer('doublePtr',x);
xp.Value
MATLAB displays:
ans =
1 2 3 4 5 6 7 8 9 10Use the plus operator to create a new libpointer that is offset from xp:
xp2 = xp+4; xp2.Value
MATLAB displays:
ans =
5 6 7 8 9 10Note The new pointer (xp2 in this example) is valid only as long as the original pointer, xp, exists. |
If a function has an input argument that is a pointer to a structure, you can either pass the structure itself, or pass a pointer to the structure. Creating a pointer to a structure is similar to creating a pointer to a primitive type.
The addStructByRef function in the shrlibsample library takes a pointer to a structure of type c_struct. The output argument is the sum of all fields in the structure. The function also modifies the fields of the input structure. Here is the C function:
EXPORTED_FUNCTION double addStructByRef(struct c_struct *st) {
double t = st->p1 + st->p2 + st->p3;
st->p1 = 5.5;
st->p2 = 1234;
st->p3 = 12345678;
return t;
}Although the input to the addStructByRef function is a pointer to a structure, you can pass the structure itself and let MATLAB make the conversion to a pointer.
In the following example, create the structure sm and call addStructByRef:
sm.p1 = 476; sm.p2 = -299; sm.p3 = 1000;
x = calllib('shrlibsample', 'addStructByRef', sm)MATLAB displays:
x =
1177However, MATLAB does not modify the contents of sm, since it is not a pointer. Type:
sm
MATLAB displays:
sm =
p1: 476
p2: -299
p3: 1000The following example passes a pointer to the structure. First, create the libpointer object:
sp = libpointer('c_struct', sm);
sp.ValueThe libpointer, sp, has the same values as the structure sm:
ans =
p1: 476
p2: -299
p3: 1000Pass the libpointer to the function:
calllib('shrlibsample', 'addStructByRef', sp)
MATLAB displays:
ans =
1177
In this case, the function modifies the structure fields. Type:
sp.Value
MATLAB displays the updated values:
ans =
p1: 5.5000
p2: 1234
p3: 12345678In cases where a function defines an input argument that is a pointer to the first element of a data array, MATLAB automatically passes an argument that is a pointer of the correct type to the first element of data in the MATLAB vector or matrix.
The following pseudo-code shows how to do this. Suppose you have a function mySum in a library myLib. The signature of the C function is:
int mySum(int size, short* data);
The C variable data is an array of type short. The equivalent MATLAB type is int16. You can pass any of the following MATLAB variables to this function:
Data = 1:100;
shortData = int16(Data); %equivalent to C short type
lp = libpointer('int16Ptr',Data); %libpointer objectThe following pseudo-code statements are equivalent:
summed_data = calllib('myLib','mySum',100,Data);
summed_data = calllib('myLib','mySum',100,shortData);
summed_data = calllib('myLib','mySum',100,lp);The length of the data vector must be equal to the specified size. For example:
% sum last 50 elements
summed_data = calllib('myLib','mySum',50,Data(51:100)); C represents characters as eight-bit integers. To use a MATLAB string as an input argument, you must convert the string to the proper type and create a voidPtr. To do this, use the libpointer function as follows:
str = 'string variable';
vp = libpointer('voidPtr',[int8(str) 0]);The syntax [int8(str) 0] creates the null-terminated string required by the C function. To read the string, and verify the pointer type, enter:
char(vp.Value) vp.DataType
MATLAB displays:
ans = string variable ans = voidPtr
You can call a function that takes a voidPtr to a string as an input argument using the following syntax because 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:
func_name([int8(str) 0])Note that while MATLAB converts the argument from a value to a pointer, it must be of the correct type.
The getListOfStrings function from the shrlibsample library returns a char **, which you can think of as a pointer to an array of strings. The function signature is:
lib.pointer getListOfStrings
Here is the getListOfStrings function in C:
EXPORTED_FUNCTION const char ** getListOfStrings(void)
{
static const char *strings[5];
strings[0]="String 1";
strings[1]="String Two";
strings[2]=""; /* empty string */
strings[3]="Last string";
strings[4]=NULL;
return strings;
}To read this array, type:
ptr = calllib('shrlibsample','getListOfStrings');
MATLAB creates a libpointer object ptr of type stringPtrPtr. This object points to the first string. To display the string, use the Value property:
ptr.Value
To view the other strings, you need to increment the pointer. For example, type:
for index = 0:3 tempPtr = ptr+index; tempPtr.Value end
MATLAB displays:
ans =
'String 1'
ans =
'String Two'
ans =
{''}
ans =
'Last string'The getListOfStrings function returns a lib.pointer which you can use to create a MATLAB cell array of strings.
To call the function, type:
if not(libisloaded('shrlibsample'))
addpath(fullfile(matlabroot , 'extern', 'examples', 'shrlib'));
loadlibrary shrlibsample shrlibsample.h;
end
ptr = calllib('shrlibsample','getListOfStrings');Create indexing variables to iterate through the arrays. Use ptrindex for the strings returned by the function and index for the MATLAB array:
ptrindex = ptr; index=1;
Create the cell array of strings, mlStringArray:
while ischar(ptrindex.value{1}) %stop at end of list (NULL)
mlStringArray{index} = ptrindex.value{1};
ptrindex = ptrindex+1; %increment pointer
index = index+1; %increment array index
endTo view the contents of the cell array, type:
mlStringArray
MATLAB displays:
mlStringArray =
'String 1' 'String Two' '' 'Last string'
In general, MATLAB passes a valid memory address each time you pass a variable to a library function. You should use a libpointer object in cases where the library stores the pointer and accesses the buffer over a period of time. In these cases, you need to ensure that MATLAB has control over the lifetime of the buffer and to 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 libpointer in this situation.
Suppose an external library myLib has the following functions:
AcquireData(int points, short *buffer) IsAquisitionDone(void)
where buffer is declared as follows:
short buffer[99]
First, create a libpointer 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)
endThe following statement reads the data in the buffer:
result = pBuffer.Value;
When the library is done with the buffer, clear the MATLAB variable:
clear pBuffer
Multilevel pointers are arguments that have more than one level of referencing. A multilevel pointer type in MATLAB uses the suffix PtrPtr. For example, use doublePtrPtr for the C argument double **.
When calling a function that takes a multilevel pointer argument, use a libpointer object and let MATLAB convert it to the multilevel pointer. For example, the allocateStruct function in the shrlibsample library takes a c_structPtrPtr argument. The signature for this function is:
c_structPtrPtr allocateStruct(c_structPtrPtr)
Here is the C function:
EXPORTED_FUNCTION void allocateStruct(struct c_struct **val)
{
*val=(struct c_struct*) malloc(sizeof(struct c_struct));
(*val)->p1 = 12.4;
(*val)->p2 = 222;
(*val)->p3 = 333333;
}Create a libpointer object of type c_structPtr and pass it to the function:
sp = libpointer('c_structPtr');
calllib('shrlibsample', 'allocateStruct', sp)
get(sp)
MATLAB displays:
ans =
Value: [1x1 struct]
DataType: 'c_structPtr'
Type:
sp.Value
MATLAB displays:
ans =
p1: 12.4000
p2: 222
p3: 333333When you use allocateStruct, you must free memory using the command:
calllib('shrlibsample', 'deallocateStruct', sp)Suppose you have a library, myLib, with a function, acquireString, that reads an array of strings. The function signature is:
char** acquireString(void)
The following pseudo-code shows how to manipulate the return value, an array of pointers to strings.
ptr = calllib(myLib,'acquireString');
MATLAB creates a libpointer object ptr of type stringPtrPtr. This object points to the first string. To view other strings, you need to increment the pointer. For example, to display the first 3 strings, type:
for index = 0:2 tempPtr = ptr+index; tempPtr.Value end
MATLAB displays:
ans =
'str1'
ans =
'str2'
ans =
'str3'
![]() | Passing Arguments to Shared Library Functions | Working with Structures | ![]() |

Includes the most popular MATLAB recorded presentations with Q&A; sessions led by MATLAB experts.
| © 1984-2011- The MathWorks, Inc. - Site Help - Patents - Trademarks - Privacy Policy - Preventing Piracy - RSS |