# Calling Sparse Solver and Preconditioner Routines from C/C++

The calling interface for all of the Intel MKL sparse solver and preconditioner routines is designed to be used easily from FORTRAN 77 or Fortran 90. However, any of these routines can be invoked directly from C or C++ if users are familiar with the inter-language calling conventions of their platforms. These conventions include, but are not limited to, the argument passing mechanisms for the language, the data type mappings from Fortran to C/C++, and the platform specific method of decoration for Fortran external names.

To promote portability, the C header files provide a set of macros and type definitions intended to hide the inter-language calling conventions and provide an interface to the Intel MKL sparse solver routines that appears natural for C/C++.

For example, consider a hypothetical library routine foo that takes a real vector of length n, and returns an integer status. Fortran users would access such a function as:
`INTEGER n, status, foo`
`REAL x(*)`
`status = foo(x, n)`

As noted above, to invoke foo, C users need to know what C data types correspond to Fortran types INTEGER and REAL; what argument passing mechanism the Fortran compiler uses; and what, if any, name decoration the Fortran compiler performs when generating the external symbol foo.

However, by using the C specific header file, for example mkl_solver.h, the invocation of foo, within a C program would look as follows:
`#include "mkl_solver.h"`
`_INTEGER_t i, status;`
`_REAL_t x[];`
`status = foo( x, i );`

Note that in the above example, the header file mkl_solver.h provides definitions for the types _INTEGER_t and _REAL_t that correspond to the Fortran types INTEGER and REAL.

To simplify calling of the Intel MKL sparse solver routines from C and C++, the following approach of providing C definitions of Fortran types is used: if an argument or a result from a sparse solver is documented as having the Fortran language specific type XXX, then the C and C++ header files provide an appropriate C language type definitions for the name _XXX_t.

## Caveat for C Users

One of the key differences between C/C++ and Fortran is the argument passing mechanisms for the languages: Fortran programs use pass-by-reference semantics and C/C++ programs use pass-by-value semantics. In the above example, the header file mkl_solver.h attempts to hide this difference, by defining a macro foo, which takes the address of the appropriate arguments. For example, on the Tru64 UNIX* operating system mkl_solver.h defines the macro as follows:
`#define foo(a,b) foo_((a), &(b))`
Note how constants are treated when using the macro form of foo. foo( x, 10 ) is converted into `foo_( x, &10 )`. In a strictly ANSI compliant C compiler, taking the address of a constant is not permitted, so a strictly conforming program would look like:
`INTEGER_t iTen = 10;`
`_REAL_t * x;`
`status = foo( x, iTen );`

However, some C compilers in a non-ANSI compliant mode enable taking the address of a constant for ease of use with Fortran programs. The form foo( x, 10 ) is acceptable for such compilers.

Parent topic: Sparse Solver Routines