Additional Topics > External Development Guide > Adding System Routines > Example: MULT2

# Example: MULT2

The system function example shown in the following figure expects a single argument (an array). It returns a single-precision, floating-point array that contains the values from the argument, multiplied by two.

#Include the required header files.

#include <stdio.h>

#include "idl_export.h"

# Every system routine takes the same two or three arguments.

# argc is the number of arguments, argv is an array of

# arguments. This routine does not accept keywords,

# so argk is not present.

IDL_VPTR mult2(int argc, IDL_VPTR argv[])

{

# dst will become a pointer to the resulting variable’s

# descriptor. src points at the input variable which is

# found in argv[0].

IDL_VPTR dst, src;

# src_d and dst_d will point to the source and

# destination data areas.

float *src_d, *dst_d;

# n will contain the number of elements in src

int n;

src = dst = argv[0];

# The input variable will serve as both the source

# and destination. This will only be true if the

# parameter is a temporary floating-point array.

# Screen out any input that is not of a basic type,

# and only allow arrays. A better version of this

# routine would handle scalar input also, but we want

# to keep the example simple.

IDL_ENSURE_SIMPLE(src);

IDL_ENSURE_ARRAY(src);

# If the input is not of IDL_TYP_FLOAT, we call

# the IDL_CvtFlt() function to create a floating-point

# copy of the argument (see “Converting to Specific

# Types” for information about converting types).

if (src->type != IDL_TYP_FLOAT)

src = dst = IDL_CvtFlt(1, argv);

# Initialize the pointers to the source

# and destination data areas from the array block

# structure pointed to by the input variable descriptor.

src_d = dst_d = (float *) src->value.arr->data;

# If the input variable is not a temporary variable,

# we cannot change its value and return it as the function

# result. Instead, allocate a new temporary floating point

# array into which the result will be placed. Notice how

# the number of dimensions and their sizes are taken from

# the source variable array block.

if (!(src->flags & IDL_V_TEMP))

dst_d = (float *)

IDL_MakeTempArray(IDL_TYP_FLOAT,src->value.arr->n_dim,

src->value.arr->dim,

IDL_ARR_INI_NOP, &dst);

# Loop over each element of the arrays.

# Do the multiplication for each element.

# Return the temporary variable containing the result.

for (n = src->value.arr->n_elts; n--; )

*dst_d++ = 2.0 * *src_d++;

return(dst);

}

Note that the routine could also be written more efficiently with a SWITCH statement in C, which would handle each of the eight possible data types and eliminate conversion of the input parameter.

### Testing the Example

Once we have compiled the function and linked it into IDL (possibly using LINKIMAGE), we can use the built-in IDL function INDGEN to test the new function, which we name MULT2. INDGEN returns an array of values with each element set to the value of its array index. Therefore, the statement:

PRINT, INDGEN(5)

prints the following on the screen:

0 1 2 3 4

To test our new function we use INDGEN to provide an input argument:

PRINT, MULT2(INDGEN(5))

The result, as expected, is:

0.00000 2.00000 4.00000 6.00000 8.00000