Parameters must be registered in the master function with the MfuncParam...() function that matches the data type of the parameter (for example, a parameter of type MIL_INT should be registered using MfuncParamMilInt()); the values of the parameters passed to the master function must then be retrieved from within the slave function using the corresponding MfuncParamValue...(). You can alternatively use the general form of the above functions, MfuncParam() and MfuncParamValue(), respectively.
Certain parameter registration functions require additional details about the parameter being registered:
When registering parameters of type MIL_ID (using MfuncParamMilId(), MfuncParamArrayMilId(), or MfuncParamConstArrayMilId()), you must specify the type of MIL object.
When registering parameters that accept pointers (using MfuncParamDataPointer() or MfuncParamConstDataPointer()), you must specify the size of the data, in bytes.
When registering parameters that accept strings (using MfuncParamMilText(), MfuncParamConstMilText(), or MfuncParamFilename()), you must specify the number of characters in the string, including the null terminator.
When registering parameters of type MIL_ID (using MfuncParamMilId(), MfuncParamArrayMilId(), or MfuncParamConstArrayMilId()) or parameters that accept strings or pointers, you must specify whether the parameter will serve as input (M_IN), output (M_OUT), or both (M_IN + M_OUT) for your function. Your slave function should use output parameters to return results (for example, the destination buffer of an operation should be passed as an output parameter).
The M_IN and M_OUT attributes of the MfuncParam...() functions do not serve to limit the slave function's ability to modify variables; rather, the M_OUT attribute serves to indicate to MIL that when the slave function finishes, MIL must synchronize the slave function's data for that parameter with the rest of the application. Identifying output parameters is particularly important when the slave function is being executed by a remote processor which does not have direct access to the Host's address space. In this case, when the slave function terminates, MIL will internally pass the new values for the output type parameters to the Host. If the content of a buffer is modified in a slave function executed by a remote processor, and the buffer was not registered as an output parameter, your changes will be lost when the slave function finishes.
From within the slave function, you must declare a new variable for each parameter registered in the master function; the data type of each new variable must match the data type of its associated parameter. For example, a parameter of type MIL_ID must be registered using MfuncParamMilId() in the master function; then, in the slave function, you must declare a new variable of type MIL_ID and use MfuncParamValueMilId() to associate the new variable with the value passed as a parameter to the master function.
Note that, if you are using an output pointer parameter, your function context must be allocated to run synchronously.
When registering a parameter, you can call the general function MfuncParam(), which you can use to register any type of parameter, or you can call a data-type specific MfuncParam...() function, such as MfuncParamMilId() and MfuncParamMilInt(). MfuncParam() will internally call the appropriate data-type specific version based on the values you specify in the function.
Similarly to MfuncParam(), when reading the value of a parameter registered in the master function, you can call the general function MfuncParamValue(), or you can call a data-type specific MfuncParamValue...() function, such as MfuncParamValueMilId() and MfuncParamValueMilInt().
Only synchronous user-defined MIL functions (MfuncAlloc() with M_SYNCHRONOUS_FUNCTION) can have a return value. To have a user-defined MIL function return a value, the return value must be generated in the slave function and returned by the master function. However, the slave function of a user-defined MIL function must be declared as being of type void MFTYPE; therefore, slave functions can't directly return a value. To return a value, the master function must declare a variable (the return variable) and register a pointer to it as if it was a real M_OUT parameter of the master function. The slave function should treat the return variable as a regular M_OUT parameter.
Note that the number of parameters specified during context allocation in a user-defined MIL function (MfuncAlloc()) limits the number of parameters that the slave function can retrieve. If a user-defined MIL function has a return value, the number of parameters must be set to one greater than is actually passed to the master function. The address of the return variable must be registered as a pointer parameter in the master function (MfuncParamDataPointer() or MfuncParamArrayMilId() with Attribute set to M_OUT). Then, in the slave function, you must declare a pointer variable of the same type as the return variable and associate the pointer with the address of the return variable using MfuncParamValue(). Recall that, the slave function does not actually store the return value at the memory address provided by the master function; it provides the master function with the new value to be written to memory.
The following portion of MIL code shows the master function of a user-defined MIL function with a return value:
int MyFunc( MIL_ID SrcImage ) {
MIL_ID MyFunctionContext;
int ReturnValue = 0;
MfuncAlloc( MIL_TEXT("MyFunc"), 2, MyFuncSlave, M_NULL, M_NULL,
M_USER_MODULE_1+1, M_SYNCHRONOUS_FUNCTION+M_LOCAL,
&MyFunctionContext );
MfuncParamMilId ( MyFunctionContext, 1, SrcImage, M_IMAGE, M_IN+M_PROC );
MfuncParamDataPointer ( MyFunctionContext, 2, &ReturnValue, sizeof(ReturnValue), M_OUT );
MfuncCall( MyFunctionContext );
MfuncFree( MyFunctionContext );
return ReturnValue;
}
The following portion of MIL code shows how to retrieve the address of the return variable and use it to store the return value (in the slave function):
void MFTYPE MyFuncSlave( MIL_ID Func ){
MIL_ID SrcImage;
int *ReturnValuePtr;
int ValueToReturn = 0;
MfuncParamValue( Func, 1, &SrcImage );
MfuncParamValue( Func, 2, &ReturnValuePtr );
/* Calculate the return value */
// ValueToReturn = ...
*ReturnValuePtr = ValueToReturn;
}