This example focuses on creating, registering, using, and unregistering callbacks. A callback requires a certain function signature, which allows it to be registered to and access a node. Events, while slightly more complex, follow this same pattern.
Once comfortable with NodeMapCallback_C, we suggest checking out any of the events examples: EnumerationEvents_C, ImageEvents_C, or Logging_C.
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#define MAX_BUFF_LEN 256
typedef struct
{
size_t size;
size_t capacity;
{
}
{
{
}
}
{
{
printf("Error: Attempt to pop from an empty array..\n\n");
}
}
{
}
{
}
{
}
{
{
}
return pbReadable;
}
{
{
}
return pbWritable;
}
{
printf("Unable to get %s (%s %s retrieval failed).\n\n", node, name, node);
}
{
int64_t height = 0;
{
{
printf("Unable to retrieve height. Non-fatal error %d...\n\n", err);
return;
}
}
else
{
return;
}
printf("Height callback message:\n");
printf("\tLook! Height changed to %d...\n\n", (int)height);
}
{
double gain = 0.0;
{
{
printf("Unable to retrieve gain. Non-fatal error %d...\n\n", err);
return;
}
}
else
{
return;
}
printf("Gain callback message:\n");
printf("\tLook now! Gain changed to %f...\n\n", gain);
}
{
{
strcpy(nodeName, "Unknown name");
}
{
{
printf(
"Unable to retrieve node type. Non-fatal error: %s [%d]\n\n",
GetLastErrorMessage(), err);
return;
}
}
else
{
return;
}
{
int64_t featureValue = 0;
printf("\t%s was changed to %lld\n", nodeName, featureValue);
}
{
if (featureValue)
{
printf("\t%s was changed to true\n", nodeName);
}
else
{
printf("\t%s was changed to false\n", nodeName);
}
}
{
double featureValue = 0.0;
printf("\t%s was changed to %f\n", nodeName, featureValue);
}
{
printf("\t%s was changed to %s\n", nodeName, featureValue);
}
else
{
printf("\t%s with node type %d was updated\n", nodeName, nodeType);
}
}
{
printf("\n\n*** CONFIGURING CALLBACKS ***\n\n");
int64_t gainAutoOff = 0;
{
printf("Unable to disable automatic gain (node retrieval). Aborting with error %d...\n\n", err);
return err;
}
{
{
printf("Unable to disable automatic gain (enum entry retrieval). Aborting with error %d...\n\n", err);
return err;
}
}
else
{
}
{
{
printf(
"Unable to disable automatic gain (enum entry int value retrieval). Aborting with error %d...\n\n",
err);
return err;
}
}
else
{
}
{
{
printf("Unable to disable automatic gain (enum entry setting). Aborting with error %d...\n\n", err);
return err;
}
}
else
{
}
printf("Automatic gain disabled...\n");
{
printf("Unable to register height callback (node retrieval). Aborting with error %d...\n\n", err);
return err;
}
{
printf("Unable to register height callback (callback registration). Aborting with error %d...\n\n", err);
return err;
}
push(handleArray, callbackHeight, hHeight);
printf("Height callback registered...\n");
{
printf("Unable to register gain callback (callback registration). Aborting with error %d...\n\n", err);
return err;
}
{
printf("Unable to register gain callback (callback registration). Aborting with error %d...\n\n", err);
return err;
}
push(handleArray, callbackGain, hGain);
printf("Gain callback registered...\n\n");
return err;
}
{
size_t numEntries = 0;
{
printf(
"Unable to retrieve event selector entries. Aborting with error: %s [%d]\n\n",
GetLastErrorMessage(), err);
return err;
}
{
{
printf(
"Unable to retrieve number of entries. Aborting with error: %s [%d]\n\n",
GetLastErrorMessage(), err);
return err;
}
}
else
{
printf(
"Unable to read number of entries. Aborting with error: %s [%d]\n\n",
GetLastErrorMessage(), err);
return err;
}
*numEvents = numEntries;
return err;
}
{
size_t numEntries = 0;
printf("\n\n*** CONFIGURING EVENT CALLBACKS ***\n\n");
{
printf("Unable to retrieve event selector entries. Skipping...\n\n");
}
{
{
printf("Unable to retrieve event selector entries. Skipping...\n\n");
}
}
else
{
printf("Unable to retrieve event selector entries. Skipping...\n\n");
}
for (unsigned int i = 0; i < numEntries; i++)
{
{
continue;
}
{
{
printf("\t%s: unable to retrieve event entry by display name (error %d)...\n", entryName, err);
}
}
else
{
continue;
}
int64_t value = 0;
{
printf("\t%s: unable to get event entry value (error %d)...\n", entryName, err);
continue;
}
{
{
printf("\t%s: unable to set event entry value (error %d)...\n", entryName, err);
continue;
}
}
else
{
printf("\t%s: unable to set event entry value (error %d)...\n", entryName, err);
continue;
}
{
printf("\t%s: unable to get entry from nodemap (error %d)...\n", entryName, err);
continue;
}
int64_t eventNotificationOn = 0;
if (
IsReadable(hEventNotification,
"EventNotification"))
{
{
printf(
"Unable to set event notification to On (entry 'On' retrieval). Aborting with error "
"%d...\n\n",
err);
continue;
}
}
else
{
printf(
"Unable to read event notification mode. Aborting with error: %s [%d]\n\n",
GetLastErrorMessage(), err);
continue;
}
if (
IsReadable(hEventNotificationOn,
"EventNotificationOn"))
{
{
printf(
"Unable to set event notification to On (entry int value retrieval). Aborting with error "
"%d...\n\n",
err);
continue;
}
}
else
{
printf(
"Unable to read event notification On. Aborting with error: %s [%d]\n\n",
err);
continue;
}
if (
IsWritable(hEventNotification,
"EventNotification"))
{
{
printf(
"Unable to set event notification to On (entry int value setting). Aborting with error "
"%d...\n\n",
err);
continue;
}
printf("\t%s: enabled...\n", entryName);
}
else
{
printf(
"Unable to write to event notification. Aborting with error: %s [%d]\n\n",
GetLastErrorMessage(), err);
continue;
}
{
return err;
}
sprintf(eventDataCategoryName, "Event%sData", entrySymbolic);
size_t numFeatures;
{
printf("\t%s: unable to get entry from nodemap (error %d)...\n", eventDataCategoryName, err);
continue;
}
if (!
IsReadable(hDataCategory, eventDataCategoryName))
{
printf("Unable to retrieve %s. Aborting...\n\n", eventDataCategoryName);
continue;
}
{
printf("Unable to retrieve number of nodes (error %d)...\n\n", err);
return err;
}
for (unsigned int j = 0; j < numFeatures; j++)
{
if (
IsReadable(hDataCategory, eventDataCategoryName))
{
{
printf("Unable to retrieve node (error %d)...\n\n", err);
continue;
}
}
else
{
printf("Unable to retrieve node (error %d)...\n\n", err);
continue;
}
{
strcpy(featureName, "Unknown name");
}
{
printf(
"Unable to register %s callback (callback registration). Aborting with error %d...\n\n",
featureName,
err);
continue;
}
push(handleArray, tmpNodeCallbackHandle, hFeatureNode);
printf("\t\t%s callback registered...\n", featureName);
}
}
return err;
}
{
printf("\n*** CHANGING HEIGHT & GAIN ***\n\n");
int64_t heightToSet = 0;
int64_t heightMax = 0;
{
printf("Unable to change height (node retrieval). Aborting with error %d...\n\n", err);
return err;
}
{
{
printf("Unable to change height (max retrieval). Aborting with error %d...\n\n", err);
return err;
}
}
else
{
}
heightToSet = heightMax;
printf("Regular function message:\n");
printf("\tHeight about to be set to %d...\n\n", (int)heightToSet);
{
{
printf("Unable to change height (value setting). Aborting with error %d...\n\n", err);
return err;
}
}
else
{
}
double gainToSet = 0.0;
double gainMax = 0.0;
{
printf("Unable to register gain callback (callback registration). Aborting with error %d...\n\n", err);
return err;
}
{
{
printf("Unable to change gain (max retrieval). Aborting with error %d...\n\n", err);
return err;
}
}
else
{
}
gainToSet = gainMax / 2.0;
printf("Regular function message:\n");
printf("\tGain about to be set to %f...\n\n", gainToSet);
{
{
printf("Unable to change gain (value setting). Aborting with error %d...\n\n", err);
return err;
}
}
else
{
}
return err;
}
{
while (handleArray->
size > 0)
{
pop(handleArray, &hCallback, &hNode);
{
printf(
"Unable to deregister callback (callback deregistration). Aborting with error %d...\n\n", err);
return err;
}
{
strcpy(nodeName, "Unknown name");
}
printf("\t\t%s callback deregistered...\n", nodeName);
}
return err;
}
{
size_t numEntries = 0;
printf("\n\n*** RESETTING EVENT CALLBACKS ***\n\n");
{
printf("Unable to retrieve event selector entries. Skipping...\n\n");
}
{
{
printf("Unable to retrieve number of entries. Skipping...\n\n");
}
}
else
{
printf("Unable to read number of entries. Skipping...\n\n");
}
for (unsigned int i = 0; i < numEntries; i++)
{
{
continue;
}
{
{
printf("\t%s: unable to retrieve event entry by display name (error %d)...\n", entryName, err);
}
}
else
{
continue;
}
int64_t value = 0;
{
printf("\t%s: unable to get event entry value (error %d)...\n", entryName, err);
continue;
}
{
{
printf("\t%s: unable to set event entry value (error %d)...\n", entryName, err);
continue;
}
}
else
{
printf("\t%s: unable to set event entry value (error %d)...\n", entryName, err);
continue;
}
{
printf("\t%s: unable to get entry from nodemap (error %d)...\n", entryName, err);
continue;
}
int64_t eventNotificationOn = 0;
if (
IsReadable(hEventNotification,
"EventNotification"))
{
{
printf(
"Unable to set event notification to Off (entry 'Off' retrieval). Aborting with error "
"%d...\n\n",
err);
continue;
}
}
else
{
printf(
"Unable to read event notification mode. Aborting with error: %s [%d]\n\n",
GetLastErrorMessage(), err);
continue;
}
if (
IsReadable(hEventNotificationOff,
"EventNotificationOff"))
{
{
printf(
"Unable to set event notification to Off (entry int value retrieval). Aborting with error "
"%d...\n\n",
err);
continue;
}
}
else
{
printf(
"Unable to read event notification Off. Aborting with error: %s [%d]\n\n",
GetLastErrorMessage(), err);
continue;
}
if (
IsWritable(hEventNotification,
"EventNotification"))
{
{
printf(
"Unable to set event notification to Off (entry int value setting). Aborting with error "
"%d...\n\n",
err);
continue;
}
printf("\t%s: disabled...\n", entryName);
}
else
{
printf(
"Unable to write to event notification. Aborting with error: %s [%d]\n\n",
GetLastErrorMessage(), err);
continue;
}
}
return err;
}
{
int64_t gainAutoContinuous = 0;
{
printf("Unable to disable automatic gain (node retrieval). Aborting with error %d...\n\n", err);
return err;
}
{
{
printf("Unable to enable automatic gain (enum entry retrieval). Aborting with error %d...\n\n", err);
return err;
}
}
else
{
}
if (
IsReadable(hGainAutoContinuous,
"GainAutoContinuous"))
{
{
printf(
"Unable to enable automatic gain (enum entry int value retrieval). Aborting with error %d...\n\n", err);
return err;
}
}
else
{
}
{
{
printf("Unable to enable automatic gain (enum entry setting). Aborting with error %d...\n\n", err);
return err;
}
printf("Automatic gain turned back on...\n\n");
}
else
{
}
return err;
}
{
printf("\n*** IMAGE ACQUISITION ***\n\n");
int64_t acquisitionModeContinuous = 0;
{
return err;
}
if (
IsReadable(hAcquisitionMode,
"AcquisitionMode"))
{
{
return err;
}
}
else
{
}
if (
IsReadable(hAcquisitionModeContinuous,
"AcquisitionModeContinuous"))
{
{
return err;
}
}
else
{
}
if (
IsWritable(hAcquisitionMode,
"AcquisitionMode"))
{
{
return err;
}
}
else
{
}
printf("Acquisition mode set to continuous...\n");
{
return err;
}
printf("Acquiring images...\n");
{
strcpy(deviceSerialNumber, "");
lenDeviceSerialNumber = 0;
}
else
{
if (
IsReadable(hDeviceSerialNumber,
"DeviceSerialNumber"))
{
err =
spinStringGetValue(hDeviceSerialNumber, deviceSerialNumber, &lenDeviceSerialNumber);
{
strcpy(deviceSerialNumber, "");
lenDeviceSerialNumber = 0;
}
}
else
{
strcpy(deviceSerialNumber, "");
lenDeviceSerialNumber = 0;
}
printf("Device serial number retrieved as %s...\n", deviceSerialNumber);
}
printf("\n");
const unsigned int k_numImages = 10;
unsigned int imageCnt = 0;
{
printf("Unable to create image processor. Non-fatal error %d...\n\n", err);
}
{
printf("Unable to set image processor color processing method. Non-fatal error %d...\n\n", err);
}
for (imageCnt = 0; imageCnt < k_numImages; imageCnt++)
{
{
continue;
}
{
}
if (isIncomplete)
{
{
printf("Unable to retrieve image status. Non-fatal error %d...\n\n", imageStatus);
}
else
{
printf("Image incomplete with image status %d...\n", imageStatus);
}
}
if (hasFailed)
{
{
}
continue;
}
size_t width = 0;
size_t height = 0;
printf("Grabbed image %d, ", imageCnt);
{
printf("width = unknown, ");
}
else
{
printf("width = %u, ", (unsigned int)width);
}
{
printf("height = unknown\n");
}
else
{
printf("height = %u\n", (unsigned int)height);
}
{
}
{
}
{
}
{
}
}
{
printf("Unable to destroy image processor. Non-fatal error %d...\n\n", err);
}
{
}
return err;
}
{
unsigned int i = 0;
printf("\n*** DEVICE INFORMATION ***\n\n");
{
printf("Unable to retrieve node. Non-fatal error %d...\n\n", err);
return err;
}
size_t numFeatures = 0;
if (
IsReadable(hDeviceInformation,
"DeviceInformation"))
{
{
printf("Unable to retrieve number of nodes. Non-fatal error %d...\n\n", err);
return err;
}
}
else
{
}
for (i = 0; i < numFeatures; i++)
{
{
printf("Unable to retrieve node. Non-fatal error %d...\n\n", err);
continue;
}
{
strcpy(featureName, "Unknown name");
}
{
{
printf("Unable to retrieve node type. Non-fatal error %d...\n\n", err);
continue;
}
}
else
{
printf("%s: Node not readable\n", featureName);
continue;
}
{
strcpy(featureValue, "Unknown value");
}
printf("%s: %s\n", featureName, featureValue);
}
printf("\n");
return err;
}
{
{
printf("Unable to retrieve TL device nodemap (non-fatal error %d)...\n\n", err);
}
else
{
}
{
printf("Unable to retrieve TL stream nodemap (non-fatal error %d)...\n\n", err);
}
{
printf("Unable to initialize camera. Aborting with error %d...\n\n", err);
return err;
}
{
printf("Unable to retrieve GenICam nodemap. Aborting with error %d...\n\n", err);
return err;
}
{
return err;
}
{
return err;
}
{
return err;
}
{
return err;
}
{
return err;
}
{
return err;
}
{
return err;
}
{
return err;
}
{
return err;
}
{
return err;
}
{
return err;
}
{
printf("Unable to deinitialize camera. Non-fatal error %d...\n\n", err);
return err;
}
return err;
}
{
unsigned int i = 0;
printf("Application build date: %s %s \n\n", __DATE__, __TIME__);
{
printf("Unable to retrieve system instance. Aborting with error %d...\n\n", err);
return err;
}
spinLibraryVersion hLibraryVersion;
printf(
"Spinnaker library version: %d.%d.%d.%d\n\n",
hLibraryVersion.major,
hLibraryVersion.minor,
hLibraryVersion.type,
hLibraryVersion.build);
{
printf("Unable to create camera list. Aborting with error %d...\n\n", err);
return err;
}
{
printf("Unable to retrieve camera list. Aborting with error %d...\n\n", err);
return err;
}
size_t numCameras = 0;
{
printf("Unable to retrieve number of cameras. Aborting with error %d...\n\n", err);
return err;
}
printf("Number of cameras detected: %u\n\n", (unsigned int)numCameras);
if (numCameras == 0)
{
{
printf("Unable to clear camera list. Aborting with error %d...\n\n", err);
return err;
}
{
printf("Unable to destroy camera list. Aborting with error %d...\n\n", err);
return err;
}
{
printf("Unable to release system instance. Aborting with error %d...\n\n", err);
return err;
}
printf("Not enough cameras!\n");
printf("Done! Press Enter to exit...\n");
getchar();
return -1;
}
for (i = 0; i < numCameras; i++)
{
printf("\nRunning example for camera %d...\n", i);
{
printf("Unable to retrieve camera from list. Aborting with error %d...\n\n", err);
errReturn = err;
}
else
{
{
errReturn = err;
}
}
{
errReturn = err;
}
printf("Camera %d example complete...\n\n", i);
}
{
printf("Unable to clear camera list. Aborting with error %d...\n\n", err);
return err;
}
{
printf("Unable to destroy camera list. Aborting with error %d...\n\n", err);
return err;
}
{
printf("Unable to release system instance. Aborting with error %d...\n\n", err);
return err;
}
printf("\nDone! Press Enter to exit...\n");
getchar();
return errReturn;
}