The Wayback Machine - https://web.archive.org/web/20110927002820/http://www.mathworks.com:80/help/techdoc/matlab_external/f42650.html
Skip to Main Content Skip to Search
Product Documentation

Working with Pointers

The libpointer Object

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:

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.

Constructing a libpointer Object

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'

Reading a libpointer Object

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.

Creating a Pointer to a Primitive Type

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 =
     15

Reading Function Return Values

In 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 =
    75

Like 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.

Creating a Pointer by Offsetting from an Existing libpointer

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    10

Use 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    10

Creating a Pointer to a Structure

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

Passing the Structure Itself

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 =
        1177

However, MATLAB does not modify the contents of sm, since it is not a pointer. Type:

sm

MATLAB displays:

sm = 
    p1: 476
    p2: -299
    p3: 1000

Passing a Structure Pointer

The following example passes a pointer to the structure. First, create the libpointer object:

sp = libpointer('c_struct', sm);
sp.Value

The libpointer, sp, has the same values as the structure sm:

ans = 
    p1: 476
    p2: -299
    p3: 1000

Pass 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: 12345678

Passing a Pointer to the First Element of an Array

In 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 object

The 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)); 

Putting a String into a Void Pointer

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.

Passing an Array of Strings

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'

Example — Creating a Cell Array from a libpointer

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
end

To view the contents of the cell array, type:

mlStringArray

MATLAB displays:

mlStringArray = 
    'String 1'    'String Two'     ''    'Last string'

Memory Allocation for an External Library

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)
end

The 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

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: 333333

When you use allocateStruct, you must free memory using the command:

calllib('shrlibsample', 'deallocateStruct', sp)

Returning an Array of Strings

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'
  


Recommended Products

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