Examples¶
Introduction Example¶
Example for a simple C function that adds three different parameters and a returns the sum value. The Igor code assumes that a libHandle from a loaded library with FCALL_LoadLibrary was set. First a reusable JSON object for the input parameters of AddValue is created with the utility function FCALL_SetupParameterIn. As the parameter types of the C function stay constant this has to be done only once.
For a function call only the values of the parameters have to be set. When done the JSON object is converted to its string form and used with FCALL_CallFunction.
After the call finished the JSONXOP can be used again for easy parsing of the output.
int AddValues(int a, short b, char c);
// setup once
variable jsonID = FCALL_SetupParameterIn("INT32;INT32;INT16;INT8")
string parameterOut
// for each call set input values, we set here a=1, b=2 and c=3.
JSONXOP_AddValue/O/I=1 jsonID, "/Parameter/0/value"
JSONXOP_AddValue/O/I=2 jsonID, "/Parameter/1/value"
JSONXOP_AddValue/O/I=3 jsonID, "/Parameter/2/value"
// Retrieve json in string form in S_Value
JSONXOP_Dump jsonID
// issue function call
FCALL_CallFunction libHandle, "AddValues", S_Value, parameterOut
// Retrieve result
variable jsonIDOut
JSONXOP_Parse parameterOut; AbortOnRTE
jsonIDOut = V_Value
JSONXOP_GetValue/V jsonIDOut, "/result/value"; AbortOnRTE
printf "a + b + c = %d\r", V_Value
JSONXOP_Release jsonIDOut
PrintFreeDiskSpace¶
The first real world example shows the usage of the GetDiskFreeSpaceExA function of kernel32.dll that is part of the Windows operating system. At first code block the declaration is shown as present in fileapi.h that is part of the Windows SDK. The second code block shows how the CallFunction XOP is used to retrieve the free disk space. In this example the setup of the JSON object used for input is shown in detail. The function FCALL_GetParameterInJSON creates a skeleton JSON object for four (yet) empty input parameters. Then each type is set with an own call of JSONXOP_AddValue. In the next step all values for the parameters are set. Notably the latter three input parameters are pointers to 64 bit integers where data is returned. For these three single element UINT64 waves are created. The last three parameters are set with type WAVEREF and the path to the waves are set as value.
After the JSON object is fully setup it is dumped to its string form and GetDiskFreeSpaceExA is called. When FCALL_CallFunction returns the output is checked if an error was encountered. If everything went well the GetDiskFreeSpaceExA wrote the returned values directly into the 64 bit integer waves.
BOOL GetDiskFreeSpaceExA(
LPCSTR lpDirectoryName,
PULARGE_INTEGER lpFreeBytesAvailableToCaller,
PULARGE_INTEGER lpTotalNumberOfBytes,
PULARGE_INTEGER lpTotalNumberOfFreeBytes
);
1#pragma TextEncoding="UTF-8"
2#pragma rtGlobals=3 // Use modern global access method and strict wave access.
3
4#include "FCALL_functions"
5
6// The function GetDiskFreeSpaceExA is exported by kernel32.dll and declared in Fileapi.h
7// See also https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getdiskfreespaceexa
8//
9//BOOL GetDiskFreeSpaceExA(
10// LPCSTR lpDirectoryName,
11// PULARGE_INTEGER lpFreeBytesAvailableToCaller,
12// PULARGE_INTEGER lpTotalNumberOfBytes,
13// PULARGE_INTEGER lpTotalNumberOfFreeBytes
14//);
15//
16// For the parameters we use the following types: STRING, WAVEREF, WAVEREF, WAVEREF
17// The waves have one element of type UINT64, that corresponds to ULARGE_INTEGER
18
19static Constant MEGABYTE = 1048576
20
21Function PrintFreeDiskSpace()
22
23 string libHandle
24 string sysRoot, dllPath, functionName
25 string parameterIn
26 string parameterOut = ""
27 string errorMsg
28 variable errorCode, returnCode
29 variable jsonID
30 string diskPath = "C:\\"
31
32 sysRoot = GetEnvironmentVariable("SystemRoot")
33 dllPath = sysRoot + "\\System32\\kernel32.dll"
34 functionName = "GetDiskFreeSpaceExA"
35
36 try
37 jsonID = FCALL_GetParameterInJSON(paramCnt = 4)
38
39 // Set result type and parameter types
40 JSONXOP_AddValue/T="UINT8" jsonID, "/result/type"; AbortOnRTE
41 JSONXOP_AddValue/T="STRING" jsonID, "/Parameter/0/type"; AbortOnRTE
42 JSONXOP_AddValue/T="WAVEREF" jsonID, "/Parameter/1/type"; AbortOnRTE
43 JSONXOP_AddValue/T="WAVEREF" jsonID, "/Parameter/2/type"; AbortOnRTE
44 JSONXOP_AddValue/T="WAVEREF" jsonID, "/Parameter/3/type"; AbortOnRTE
45 // Set parameter values
46 Make/O/N=1/L/U param1, param2, param3
47 JSONXOP_AddValue/T=diskPath jsonID, "/Parameter/0/value"; AbortOnRTE
48 JSONXOP_AddValue/T=(GetWavesDataFolder(param1, 2)) jsonID, "/Parameter/1/value"; AbortOnRTE
49 JSONXOP_AddValue/T=(GetWavesDataFolder(param2, 2)) jsonID, "/Parameter/2/value"; AbortOnRTE
50 JSONXOP_AddValue/T=(GetWavesDataFolder(param3, 2)) jsonID, "/Parameter/3/value"; AbortOnRTE
51
52 JSONXOP_Dump jsonID; AbortOnRTE
53 parameterIn = S_Value
54 catch
55 errorMsg = getRTErrMessage()
56 errorCode = getRTError(1)
57 printf "Building parameterIn failed with code %d : %s\r", errorCode, errorMsg
58 endtry
59 JSONXOP_Release jsonID
60
61 FCALL_LoadLibrary dllPath, libHandle; AbortOnRTE
62
63 try
64 FCALL_CallFunction libHandle, functionName, parameterIn, parameterOut; AbortOnRTE
65 catch
66 errorMsg = getRTErrMessage()
67 errorCode = getRTError(1)
68 printf "CallFunction failed with code %d : %s\r", errorCode, errorMsg
69 endtry
70 FCALL_FreeLibrary libHandle
71
72 errorCode = FCALL_GetCallError(parameterOut, errorMsg)
73 if(errorCode)
74 printf "CallFunction returned error %d : %s\r", errorCode, errorMsg
75 return NaN
76 endif
77
78 JSONXOP_Parse parameterOut; AbortOnRTE
79 jsonID = V_Value
80 JSONXOP_GetValue/V jsonID, "/result/value"; AbortOnRTE
81 if(V_Value != 0)
82 printf "FreeBytesAvailableToCaller : %.1f MB\r", param1[0] / MEGABYTE
83 printf "TotalNumberOfBytes : %.1f MB\r", param2[0] / MEGABYTE
84 printf "TotalNumberOfFreeBytes : %.1f MB\r", param3[0] / MEGABYTE
85 else
86 printf "%s returned with error.\r", functionName
87 endif
88 JSONXOP_Release jsonID
89
90End
GetVersion¶
The kernel32.dll library of Windows also offers a function to retrieve the detailed Windows version. This example print the output of the GetVersion function. The function takes no input parameters and returns a unsigned 32 bit integer result.
DWORD GetVersion();
1#pragma TextEncoding="UTF-8"
2#pragma rtGlobals=3 // Use modern global access method and strict wave access.
3
4#include "FCALL_functions"
5
6// The function GetVersion is exported by kernel32.dll and declared in sysinfoapi.h
7// See also https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getversion
8//
9//DWORD GetVersion();
10//
11// For the parameters we leave the parameter array empty
12
13Function GetVersion()
14
15 string libHandle
16 string sysRoot, dllPath, functionName
17 string parameterIn
18 string parameterOut = ""
19 string errorMsg
20 variable errorCode
21 variable jsonID
22 variable returnValue, majorVersion, minorVersion, build
23
24 sysRoot = GetEnvironmentVariable("SystemRoot")
25 dllPath = sysRoot + "\\System32\\kernel32.dll"
26 functionName = "GetVersion"
27
28 try
29 jsonID = FCALL_GetParameterInJSON()
30
31 // Set result type for DWORD
32 JSONXOP_AddValue/T="UINT32" jsonID, "/result/type"; AbortOnRTE
33
34 // The GetVersion function has no input parameter, so we leave Parameter as empty array
35 JSONXOP_Dump jsonID; AbortOnRTE
36 parameterIn = S_Value
37 catch
38 errorMsg = getRTErrMessage()
39 errorCode = getRTError(1)
40 printf "Building parameterIn failed with code %d : %s\r", errorCode, errorMsg
41 endtry
42 JSONXOP_Release jsonID
43
44 FCALL_LoadLibrary dllPath, libHandle; AbortOnRTE
45
46 try
47 FCALL_CallFunction libHandle, functionName, parameterIn, parameterOut; AbortOnRTE
48 catch
49 errorMsg = getRTErrMessage()
50 errorCode = getRTError(1)
51 printf "CallFunction failed with code %d : %s\r", errorCode, errorMsg
52 endtry
53 FCALL_FreeLibrary libHandle
54
55 errorCode = FCALL_GetCallError(parameterOut, errorMsg)
56 if(errorCode)
57 printf "CallFunction returned error %d : %s\r", errorCode, errorMsg
58 return NaN
59 endif
60 // No Error, we can check results
61 JSONXOP_Parse parameterOut; AbortOnRTE
62 jsonID = V_Value
63 JSONXOP_GetValue/V jsonID, "/result/value"; AbortOnRTE
64 returnValue = V_Value
65 JSONXOP_Release jsonID
66
67 majorVersion = returnValue & 0xff
68 minorVersion = (returnValue & 0xff00) >> 8
69 if(returnValue < 0x80000000)
70 build = (returnValue & 0xffff0000) >> 16
71 endif
72 printf "Version is %d.%d (%d)\r", majorVersion, minorVersion, build
73End
QueryPerformanceCounter¶
The QueryPerformanceCounter function of kernel32.dll allows to retrieve the current high-precision performance counter value. In the example an inline array is used to return the value of the first input parameter. When an inline array is used the function parameter is always expected to be a pointer and the parameter type set is the pointers type. Here the parameters type is set to INT64 and the array for the value field contains a single element.
After the call the result is retrieved from the first element of the returned inline array from parameter 0 at “/Parameter/0/value/0”.
BOOL QueryPerformanceCounter(
LARGE_INTEGER *lpPerformanceCount
);
1#pragma TextEncoding="UTF-8"
2#pragma rtGlobals=3 // Use modern global access method and strict wave access.
3
4#include "FCALL_functions"
5
6// The function used here is exported by kernel32.dll and declared in profileapi.h
7// See also https://docs.microsoft.com/en-us/windows/win32/api/profileapi/nf-profileapi-queryperformancecounter
8//
9//BOOL QueryPerformanceCounter(
10// LARGE_INTEGER *lpPerformanceCount
11//);
12//
13// For the parameter an inline array is used.
14// It is read afterwards with a wave of type INT64, that corresponds to LARGE_INTEGER
15
16Function QueryPerformanceCounter()
17
18 string libHandle
19 string sysRoot, dllPath, functionName
20 string parameterIn
21 string parameterOut = ""
22 string errorMsg
23 variable errorCode, returnCode
24 variable jsonID
25
26 sysRoot = GetEnvironmentVariable("SystemRoot")
27 dllPath = sysRoot + "\\System32\\kernel32.dll"
28 functionName = "QueryPerformanceCounter"
29
30 try
31 jsonID = FCALL_GetParameterInJSON(paramCnt = 1)
32
33 // Set result type and parameter type
34 JSONXOP_AddValue/T="UINT8" jsonID, "/result/type"; AbortOnRTE
35 JSONXOP_AddValue/T="INT64" jsonID, "/Parameter/0/type"; AbortOnRTE
36 // Set as parameter value an inline array with one element
37 JSONXOP_AddTree/T=(JSON_ARRAY) jsonID, "/Parameter/0/value"; AbortOnRTE
38 JSONXOP_AddValue/I=0 jsonID, "/Parameter/0/value"; AbortOnRTE
39
40 JSONXOP_Dump jsonID; AbortOnRTE
41 parameterIn = S_Value
42 catch
43 errorMsg = getRTErrMessage()
44 errorCode = getRTError(1)
45 printf "Building parameterIn failed with code %d : %s\r", errorCode, errorMsg
46 endtry
47 JSONXOP_Release jsonID
48
49 FCALL_LoadLibrary dllPath, libHandle; AbortOnRTE
50
51 try
52 FCALL_CallFunction libHandle, functionName, parameterIn, parameterOut; AbortOnRTE
53 catch
54 errorMsg = getRTErrMessage()
55 errorCode = getRTError(1)
56 printf "CallFunction failed with code %d : %s\r", errorCode, errorMsg
57 endtry
58 FCALL_FreeLibrary libHandle
59
60 errorCode = FCALL_GetCallError(parameterOut, errorMsg)
61 if(errorCode)
62 printf "CallFunction returned error %d : %s\r", errorCode, errorMsg
63 return NaN
64 endif
65
66 // We don't have to check the returned BOOL as:
67 // quote: "On systems that run Windows XP or later, the function will always succeed and will thus never return zero."
68 JSONXOP_Parse parameterOut; AbortOnRTE
69 jsonID = V_Value
70 Make/FREE/L/N=1 wInt64
71 JSONXOP_GetValue/L=wInt64 jsonID, "/Parameter/0/value/0"
72 printf "PerformanceCount : %d\r", wInt64[0]
73 JSONXOP_Release jsonID
74End
Music Player¶
This example implements a very basic music player in Igor Pro. It uses the 64-bit version of the BASS library. It shows how the functions are setup once at the beginning and how the created JSON objects are reused on each call. The example can be run through the added Music Player menu entry.

Libarchive¶
Libarchive is a generic library to archive and unpack files and folders. This
example uses the libarchive library to unpack a e.g. zip file(s).
It shows how the functions are setup once at the beginning and how the created JSON objects
are reused on each call. The example can be found in the Examples folder in UncompressFile.ipf.
The main function is UncompressFiles(arcFileName, targetPath)
.
To uncompress demo.zip in c:\mydemo to c:\unpacked call UncompressFiles("c:\\mydemo\\demo.zip", "c:\\unpacked")
.
The files archive.dll and zlib.dll in the Examples folder are used as dynamic libraries.
Monochromator¶
In this example, an Andor Shamrock monochromator and an Andor Newton detector are controlled within Igor Pro. The live example shows how to set and read-out values from the attached monochromator and camera.

Operating the instruments is under full control of Igor Pro. The debug messages show the return values from function calls to the dll files.¶
The package requires the AndorSDK and calls functions from the following dlls:
C:\Program Files\Andor SOLIS\Drivers\Shamrock64
atshamrock.dll
ShamrockCIF.dll
C:\Program Files\Andor SOLIS\Drivers
atmcd64d.dll

A spectrum directly generated in Igor Pro, ready for further processing.¶
It should be visible from this example, that it is possible to control actual scientific hardware with Igor Pro using the CallFunction XOP.