Spinnaker C
4.3.0.189
 
EnumerationEvents_C.c

EnumerationEvents_C.c explores arrival and removal events on interfaces and the system. It relies on information provided in the Enumeration_C, Acquisition_C, and NodeMapInfo_C examples.

It can also be helpful to familiarize yourself with the NodeMapCallback_C example, as a callback can be thought of as a simpler, easier-to-use event. Although events are more cumbersome, they are also much more flexible and extensible.

Events generally require a class to be defined as an event handler; however, because C is not an object-oriented language, a pseudo-class is created using a function (or two) and a struct whereby the function(s) acts as the event handler method and the struct acts as its properties.

Please leave us feedback at: https://www.surveymonkey.com/r/TDYMVAPI More source code examples at: https://github.com/Teledyne-MV/Spinnaker-Examples Need help? Check out our forum at: https://teledynevisionsolutions.zendesk.com/hc/en-us/community/topics

//=============================================================================
// Copyright (c) 2025 FLIR Integrated Imaging Solutions, Inc. All Rights Reserved.
//
// This software is the confidential and proprietary information of FLIR
// Integrated Imaging Solutions, Inc. ("Confidential Information"). You
// shall not disclose such Confidential Information and shall use it only in
// accordance with the terms of the license agreement you entered into
// with FLIR Integrated Imaging Solutions, Inc. (FLIR).
//
// FLIR MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
// SOFTWARE, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE, OR NON-INFRINGEMENT. FLIR SHALL NOT BE LIABLE FOR ANY DAMAGES
// SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
// THIS SOFTWARE OR ITS DERIVATIVES.
//=============================================================================
#include "SpinnakerC.h"
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
// This macro helps with C-strings.
#define MAX_BUFF_LEN 256
// Helper for getting error messages
{
// Note: lastErrorMessage is shared across multiple threads; a different thread could overwrite the last error
// message before this function is called to grab the latest message
}
// This function represents the arrival event callback function on the system. Together with the function below, this
// makes up a sort of event handler pseudo-class. Notice that the function signatures must match exactly for the
// function to be accepted when creating the event handler, and notice how the user data is cast from the void pointer
// and manipulated.
void onDeviceArrivalSystem(spinCamera hCamera, void* pUserData)
{
spinError err = SPINNAKER_ERR_SUCCESS;
// Cast void pointer back to system object
spinSystem hSystem = (spinSystem*)pUserData;
// Retrieve count
spinCameraList hCameraList = NULL;
err = spinCameraListCreateEmpty(&hCameraList);
{
printf(
"Unable to create camera list (system arrival). Non-fatal error: %s [%d]\n\n", GetLastErrorMessage(), err);
return;
}
err = spinSystemGetCameras(hSystem, hCameraList);
{
printf(
"Unable to retrieve camera list (system arrival). Non-fatal error: %s [%d]\n\n",
err);
return;
}
size_t numCameras = 0;
err = spinCameraListGetSize(hCameraList, &numCameras);
{
printf(
"Unable to retrieve camera list size (system arrival). Non-fatal error: %s [%d]\n\n",
err);
return;
}
// Retrieve device serial number given the camera handle
spinNodeHandle hDeviceSerialNumber = NULL;
char deviceSerialNumber[MAX_BUFF_LEN];
size_t lenDeviceSerialNumber = MAX_BUFF_LEN;
err = spinCameraGetDeviceSerialNumber(hCamera, deviceSerialNumber, &lenDeviceSerialNumber);
{
strcpy(deviceSerialNumber, "");
lenDeviceSerialNumber = 0;
}
// Print count
printf("System event handler:\n");
printf("\tDevice %s has arrived on the system.\n", deviceSerialNumber);
printf(
"\tThere %s %u %s on the system.\n\n",
(numCameras == 1 ? "is" : "are"),
(unsigned int)numCameras,
(numCameras == 1 ? "device" : "devices"));
// Clear and destroy camera list while still in scope
err = spinCameraListClear(hCameraList);
{
printf(
"Unable to clear camera list (system arrival). Non-fatal error: %s [%d]\n\n", GetLastErrorMessage(), err);
return;
}
err = spinCameraListDestroy(hCameraList);
{
printf(
"Unable to destroy camera list (system arrival). Non-fatal error: %s [%d]\n\n", GetLastErrorMessage(), err);
return;
}
}
// This function represents a removal event callback function on the system.
void onDeviceRemovalSystem(spinCamera hCamera, void* pUserData)
{
spinError err = SPINNAKER_ERR_SUCCESS;
// Cast void pointer back to system object
spinSystem hSystem = (spinSystem*)pUserData;
// Retrieve count
spinCameraList hCameraList = NULL;
err = spinCameraListCreateEmpty(&hCameraList);
{
printf(
"Unable to create camera list (system removal). Non-fatal error: %s [%d]\n\n", GetLastErrorMessage(), err);
return;
}
err = spinSystemGetCameras(hSystem, hCameraList);
{
printf(
"Unable to retrieve camera list (system removal). Non-fatal error: %s [%d]\n\n",
err);
return;
}
size_t numCameras = 0;
err = spinCameraListGetSize(hCameraList, &numCameras);
{
printf(
"Unable to retrieve camera list size (system removal). Non-fatal error: %s [%d]\n\n",
err);
return;
}
// Retrieve device serial number given the camera handle
spinNodeHandle hDeviceSerialNumber = NULL;
char deviceSerialNumber[MAX_BUFF_LEN];
size_t lenDeviceSerialNumber = MAX_BUFF_LEN;
err = spinCameraGetDeviceSerialNumber(hCamera, deviceSerialNumber, &lenDeviceSerialNumber);
{
strcpy(deviceSerialNumber, "");
lenDeviceSerialNumber = 0;
}
// Print count
printf("System event handler:\n");
printf("\tDevice %s was removed from the system.\n", deviceSerialNumber);
printf(
"\tThere %s %u %s on the system.\n\n",
(numCameras == 1 ? "is" : "are"),
(unsigned int)numCameras,
(numCameras == 1 ? "device" : "devices"));
// Clear camera list while still in scope
err = spinCameraListClear(hCameraList);
{
printf(
"Unable to clear camera list (system removal). Non-fatal error: %s [%d]\n\n", GetLastErrorMessage(), err);
return;
}
err = spinCameraListDestroy(hCameraList);
{
printf(
"Unable to destroy camera list (system removal). Non-fatal error: %s [%d]\n\n", GetLastErrorMessage(), err);
return;
}
}
// This function checks if GEV enumeration is enabled on the system.
{
spinError err = SPINNAKER_ERR_SUCCESS;
// Retrieve TL NodeMap from the system
spinNodeMapHandle hNodeMapTLSystem = NULL;
err = spinSystemGetTLNodeMap(system, &hNodeMapTLSystem);
{
printf("Unable to retrieve TL system nodemap. error: %s [%d]\n\n", GetLastErrorMessage(), err);
return;
}
// Retrieve EnumerateGEVInterfaces node
spinNodeHandle hEnumerateGevInterfaces = NULL;
err = spinNodeMapGetNode(hNodeMapTLSystem, "EnumerateGEVInterfaces", &hEnumerateGevInterfaces);
{
printf("Unable to retrieve EnumerateGEVInterfaces node. error: %s [%d]\n\n", GetLastErrorMessage(), err);
return;
}
bool8_t pbReadable = False;
err = spinNodeIsReadable(hEnumerateGevInterfaces, &pbReadable);
{
printf(
"Unable to retrieve node readability (EnumerateGEVInterfaces node), with error: %s [%d]\n\n",
err);
return;
}
if (pbReadable)
{
// Read the status of GEV enumeration node
bool8_t gevEnabled = False;
err = spinBooleanGetValue(hEnumerateGevInterfaces, &gevEnabled);
{
printf(
"Unable to retrieve EnumerateGEVInterfaces node value. error: %s [%d]\n\n", GetLastErrorMessage(), err);
}
else if (!gevEnabled)
{
printf("WARNING: GEV Enumeration is disabled.\n");
printf("If you intend to use GigE cameras please run the EnableGEVInterfaces shortcut\n");
printf("or set EnumerateGEVInterfaces to true and relaunch your application.\n\n");
}
else
{
printf("EnumerateGEVInterfaces is enabled. Continuing..\n\n");
}
}
else
{
printf("EnumerateGEVInterfaces node is unavailable.");
}
}
// Example entry point; this function sets up the example to act appropriately
// upon arrival and removal events; please see Enumeration example for more
// in-depth comments on preparing and cleaning up the system.
int main(/*int argc, char** argv*/)
{
spinError err = SPINNAKER_ERR_SUCCESS;
unsigned int i = 0;
// Print application build information
printf("Application build date: %s %s \n\n", __DATE__, __TIME__);
// Retrieve singleton reference to system object
spinSystem hSystem = NULL;
err = spinSystemGetInstance(&hSystem);
{
printf("Unable to retrieve system instance. Aborting with error: %s [%d]\n\n", GetLastErrorMessage(), err);
return err;
}
// Check if GEV enumeration is enabled.
CheckGevEnabled(hSystem);
// Print out current library version
spinLibraryVersion hLibraryVersion;
spinSystemGetLibraryVersion(hSystem, &hLibraryVersion);
printf(
"Spinnaker library version: %d.%d.%d.%d\n\n",
hLibraryVersion.major,
hLibraryVersion.minor,
hLibraryVersion.type,
hLibraryVersion.build);
// Retrieve list of cameras from the system
spinCameraList hCameraList = NULL;
size_t numCameras = 0;
err = spinCameraListCreateEmpty(&hCameraList);
{
printf("Unable to create camera list. Aborting with error: %s [%d]\n\n", GetLastErrorMessage(), err);
return err;
}
err = spinSystemGetCameras(hSystem, hCameraList);
{
printf("Unable to retrieve camera list. Aborting with error: %s [%d]\n\n", GetLastErrorMessage(), err);
return err;
}
err = spinCameraListGetSize(hCameraList, &numCameras);
{
printf("Unable to retrieve number of cameras. Aborting with error: %s [%d]\n\n", GetLastErrorMessage(), err);
return err;
}
printf("Number of cameras detected: %u\n\n", (unsigned int)numCameras);
printf("\n*** CONFIGURE ENUMERATION EVENTS ***\n\n");
//
// Create interface event handler for the system
//
// *** NOTES ***
// The function for the system has been constructed to accept a system in
// order to print the number of cameras on the system. Notice that there
// are 3 types of event handlers that can be created: arrival event handlers, removal event handlers,
// and interface event handlers, which are a combination of arrival and removal
// event handlers. Here, the an interface event handler is created, which requires both
// an arrival event handler and a removal event handler object.
//
// *** LATER ***
// In Spinnaker C, every event handler that is created must be destroyed to avoid
// memory leaks.
//
spinInterfaceEventHandler interfaceEventHandlerSystem = NULL;
&interfaceEventHandlerSystem, onDeviceArrivalSystem, onDeviceRemovalSystem, (void*)hSystem);
{
printf(
"Unable to create interface event for system. Aborting with error: %s [%d]\n\n",
err);
return err;
}
printf("Interface event for system created...\n");
//
// Register interface event handler for the system
//
// *** NOTES ***
// Arrival, removal, and interface event handlers can all be registered to
// interfaces or the system. Do not think that interface event handlers can only be
// registered to an interface.
// Registering an interface event handler to the system is basically the same thing
// as registering that event handler to all interfaces, with the added benefit of
// not having to manage newly arrived or newly removed interfaces.
// In order to manually manage newly arrived or removed interfaces, one would need
// to implement interface arrival/removal event handlers, which are not yet supported
// in the Spinnaker C API.
//
// *** LATER ***
// Arrival, removal, and interface event handlers must all be unregistered manually.
// This must be done prior to releasing the system and while they are still
// in scope.
//
err = spinSystemRegisterInterfaceEventHandler(hSystem, interfaceEventHandlerSystem);
{
printf(
"Unable to register interface event on system. Aborting with error: %s [%d]\n\n",
err);
return err;
}
printf("Interface event registered to system...\n");
// Wait for user to plug in and/or remove camera devices
printf("Ready! Remove/Plug in cameras to test or press Enter to exit...\n");
getchar();
//
// Unregister system event handler from system object
//
// *** NOTES ***
// It is important to unregister all arrival, removal, and interface event handlers
// registered to the system.
//
err = spinSystemUnregisterInterfaceEventHandler(hSystem, interfaceEventHandlerSystem);
{
printf(
"Unable to unregister interface event from system. Aborting with error: %s [%d]\n\n",
err);
return err;
}
printf("Event handlers unregistered from system...\n");
//
// Destroy interface event handlers
//
// *** NOTES ***
// Event handlers must be destroyed in order to avoid memory leaks.
//
err = spinInterfaceEventHandlerDestroy(interfaceEventHandlerSystem);
{
printf("Unable to destroy interface event. Aborting with error: %s [%d]\n\n", GetLastErrorMessage(), err);
return err;
}
printf("System event handler destroyed...\n");
// Clear and destroy camera list before releasing system
err = spinCameraListClear(hCameraList);
{
printf("Unable to clear camera list. Aborting with error: %s [%d]\n\n", GetLastErrorMessage(), err);
return err;
}
err = spinCameraListDestroy(hCameraList);
{
printf("Unable to destroy camera list. Aborting with error: %s [%d]\n\n", GetLastErrorMessage(), err);
return err;
}
// Release system
err = spinSystemReleaseInstance(hSystem);
{
printf("Unable to release system instance. Aborting with error: %s [%d]\n\n", GetLastErrorMessage(), err);
return err;
}
printf("\nDone! Press Enter to exit...\n");
getchar();
return err;
}
spinBooleanGetValue
SPINNAKERC_API spinBooleanGetValue(spinNodeHandle hNode, bool8_t *pbValue)
Retrieves the value of a boolean node; boolean values are represented by 'True' (which equals '0') an...
spinCameraListClear
SPINNAKERC_API spinCameraListClear(spinCameraList hCameraList)
Clears a camera list.
spinSystemRegisterInterfaceEventHandler
SPINNAKERC_API spinSystemRegisterInterfaceEventHandler(spinSystem hSystem, spinInterfaceEventHandler hInterfaceEventHandler)
Registers an interface event handler (device arrival and device removal) to every interface on the sy...
spinSystemReleaseInstance
SPINNAKERC_API spinSystemReleaseInstance(spinSystem hSystem)
Releases the system; make sure handle is cleaned up properly by setting it to NULL after system is re...
GetLastErrorMessage
char * GetLastErrorMessage()
Definition: EnumerationEvents_C.c:52
spinErrorGetLastMessage
SPINNAKERC_API spinErrorGetLastMessage(char *pBuf, size_t *pBufLen)
Retrieves the error message of the last error.
spinSystemGetCameras
SPINNAKERC_API spinSystemGetCameras(spinSystem hSystem, spinCameraList hCameraList)
Retrieves a list of detected (and enumerable) cameras on the system; camera lists must be created and...
spinNodeMapHandle
void * spinNodeMapHandle
Handle for nodemap functionality.
Definition: SpinnakerGenApiDefsC.h:39
SpinnakerC.h
MAX_BUFF_LEN
#define MAX_BUFF_LEN
Definition: EnumerationEvents_C.c:46
spinSystemGetTLNodeMap
SPINNAKERC_API spinSystemGetTLNodeMap(spinSystem hSystem, spinNodeMapHandle *phNodeMap)
Retrieves the transport layer nodemap from the system.
spinSystemGetLibraryVersion
SPINNAKERC_API spinSystemGetLibraryVersion(spinSystem hSystem, spinLibraryVersion *hLibraryVersion)
Get current library version of Spinnaker.
spinSystem
void * spinSystem
Handle for system functionality.
Definition: SpinnakerDefsC.h:51
onDeviceRemovalSystem
void onDeviceRemovalSystem(spinCamera hCamera, void *pUserData)
Definition: EnumerationEvents_C.c:144
False
static const bool8_t False
Definition: SpinnakerDefsC.h:36
lenLastErrorMessage
size_t lenLastErrorMessage
Definition: EnumerationEvents_C.c:49
spinInterfaceEventHandlerDestroy
SPINNAKERC_API spinInterfaceEventHandlerDestroy(spinInterfaceEventHandler hInterfaceEventHandler)
Destroys an interface event handler (both device arrival and device removal)
spinSystemUnregisterInterfaceEventHandler
SPINNAKERC_API spinSystemUnregisterInterfaceEventHandler(spinSystem hSystem, spinInterfaceEventHandler hInterfaceEventHandler)
Unregisters an interface event handler from the system.
spinCameraGetDeviceSerialNumber
SPINNAKERC_API spinCameraGetDeviceSerialNumber(spinCamera hCamera, char *pBuf, size_t *pBufLen)
Retrieves a manufacturer specific serial number that identifies the camera.
spinCameraListDestroy
SPINNAKERC_API spinCameraListDestroy(spinCameraList hCameraList)
Destroys a camera list.
spinCameraList
void * spinCameraList
Handle for interface functionality.
Definition: SpinnakerDefsC.h:75
spinSystemGetInstance
SPINNAKERC_API spinSystemGetInstance(spinSystem *phSystem)
Retrieves an instance of the system object; the system is a singleton, so there will only ever be one...
bool8_t
uint8_t bool8_t
Definition: SpinnakerDefsC.h:35
spinInterfaceEventHandler
void * spinInterfaceEventHandler
Handle for interface event handler functionality.
Definition: SpinnakerDefsC.h:156
spinCamera
void * spinCamera
Handle for camera functionality.
Definition: SpinnakerDefsC.h:82
main
int main()
Definition: EnumerationEvents_C.c:287
spinInterfaceEventHandlerCreate
SPINNAKERC_API spinInterfaceEventHandlerCreate(spinInterfaceEventHandler *phInterfaceEventHandler, spinArrivalEventFunction pArrivalFunction, spinRemovalEventFunction pRemovalFunction, void *pUserData)
Creates an interface event handler (both device arrival and device removal)
spinNodeHandle
void * spinNodeHandle
Handle for node functionality.
Definition: SpinnakerGenApiDefsC.h:45
spinNodeIsReadable
SPINNAKERC_API spinNodeIsReadable(spinNodeHandle hNode, bool8_t *pbResult)
Checks whether a node is readable.
spinNodeMapGetNode
SPINNAKERC_API spinNodeMapGetNode(spinNodeMapHandle hNodeMap, const char *pName, spinNodeHandle *phNode)
Retrieves a node from the nodemap by name.
spinCameraListGetSize
SPINNAKERC_API spinCameraListGetSize(spinCameraList hCameraList, size_t *pSize)
Retrieves the number of cameras on a camera list.
onDeviceArrivalSystem
void onDeviceArrivalSystem(spinCamera hCamera, void *pUserData)
Definition: EnumerationEvents_C.c:64
CheckGevEnabled
void CheckGevEnabled(spinSystem system)
Definition: EnumerationEvents_C.c:224
SPINNAKER_ERR_SUCCESS
@ SPINNAKER_ERR_SUCCESS
An error code of 0 means that the function has run without error.
Definition: SpinnakerDefsC.h:233
spinCameraListCreateEmpty
SPINNAKERC_API spinCameraListCreateEmpty(spinCameraList *phCameraList)
Creates an empty camera list (camera lists created this way must be destroyed)
lastErrorMessage
char lastErrorMessage[MAX_BUFF_LEN]
Definition: EnumerationEvents_C.c:48