Impact Acquire SDK C
Callback.c

The Callback example is meant to show how to register a custom callback function to a property or feature in Impact Acquire.

Program location
The source file Callback.c can be found under:
%INSTALLDIR%\apps\Callback_C\
Note
If you have installed the package without example applications, this file will not be available. On Windows® the sample application can be installed or removed from the target system at any time by simply restarting the installation package.
Callback example:
  1. Opens a Balluff device.
  2. Shows custom callbacks.
Console Output
[0]: GX001559 (mvBlueCOUGAR-X122G, Family: mvBlueCOUGAR, interface layout: DeviceSpecific)
[1]: BF000306 (mvBlueFOX-202C, Family: mvBlueFOX, interface layout: DeviceSpecific)

Please enter the number in front of the listed device followed by [ENTER] to open it: 1
Using device number 1.
Initialising the device. This might take some time...
=== List of records BEFORE callbacks ===
This record is called 'The number of the Beast' and since creation it has been played 0 times.
This record is called 'Holy Diver' and since creation it has been played 0 times.
This record is called 'Master of Reality' and since creation it has been played 0 times.
Component 'ImageRequestTimeout_ms' did just cause a callback. It's the 1 time this function got called.
This callback carries 3 good old vinyl records with it.
  There is a record called 'The number of the Beast'
  There is a record called 'Holy Diver', which I will play now
  There is a record called 'Master of Reality'
Component 'ImageRequestTimeout_ms' did just cause a callback. It's the 2 time this function got called.
This callback carries 3 good old vinyl records with it.
  There is a record called 'The number of the Beast'
  There is a record called 'Holy Diver'
  There is a record called 'Master of Reality', which I will play now
Component 'RequestCount' did just cause a callback. It's the 3 time this function got called.
This callback carries 3 good old vinyl records with it.
  There is a record called 'The number of the Beast', which I will play now
  There is a record called 'Holy Diver'
  There is a record called 'Master of Reality'
...
How it works

This short example is meant to be self-explanatory.

Source code
/*
* @description: Example applications for Impact Acquire
* @copyright: Copyright (C) 2011 - 2023 Balluff GmbH
* @authors: APIs and drivers development team at Balluff GmbH
* @initial date: 2011-07-11
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <apps/Common/exampleHelper_C.h>
#include <mvDeviceManager/Include/mvDeviceManager.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef _WIN32
# include <conio.h> // _getch under Windows
#endif // #ifdef _WIN32
//-----------------------------------------------------------------------------
typedef struct TMatchbox
//-----------------------------------------------------------------------------
{
int matches_;
} Matchbox;
//-----------------------------------------------------------------------------
typedef struct TWallet
//-----------------------------------------------------------------------------
{
double euros_;
} Wallet;
//-----------------------------------------------------------------------------
typedef struct THandbag
//-----------------------------------------------------------------------------
{
Matchbox matchbox_;
Wallet wallet_;
} Handbag;
//-----------------------------------------------------------------------------
// Please note that this function may have more hit counts then the provoking loop
// has iterations. This is because the callback gets executed when a monitored
// feature will change in any way thus e.g. also if its visibility or max value
// changes.
//
// Please carefully read the documentation of the API functions for callback handling
// (OBJ_CreateCallback in particular) to avoid unpleasant surprises!
void DMR_CALL callbackFunction( HOBJ hObj, void* pUserData )
//-----------------------------------------------------------------------------
{
static unsigned int hitCount = 0;
Wallet* pWallet = 0;
Matchbox* pMatchbox = 0;
printf( "Hit-count: %d, hObj causing the callback: 0x%08x\n", ++hitCount, hObj );
pWallet = &( ( Handbag* )pUserData )->wallet_;
pMatchbox = &( ( Handbag* )pUserData )->matchbox_;
printf( "There are %d matches in my box and %.2f Euros in my wallet.\n", pMatchbox->matches_, pWallet->euros_ );
if( pMatchbox->matches_ > 0 )
{
--pMatchbox->matches_;
printf( "I lit a match.\n" );
}
else if( pWallet->euros_ > 0.5 )
{
pWallet->euros_ -= 0.5;
printf( "I bought a new box of matches.\n" );
pMatchbox->matches_ = 5;
}
else
{
printf( "I got no more matches and don't have enough money to buy new ones...\n" );
}
}
//-----------------------------------------------------------------------------
void checkCallbackCreation( HDRV hDrv )
//-----------------------------------------------------------------------------
{
Handbag handbag;
HOBJ hPropImageRequestTimeout_ms = getSettingProp( hDrv, "Base", "ImageRequestTimeout_ms" );
CallbackHandle hCallback = 0;
int i = 0;
if( hPropImageRequestTimeout_ms == INVALID_ID )
{
printf( "Failed to locate 'ImageRequestTimeout_ms' property.\n" );
return;
}
handbag.matchbox_.matches_ = 5;
handbag.wallet_.euros_ = 2.14;
if( ( result = OBJ_CreateCallback( ctOnChanged, callbackFunction, &handbag, &hCallback ) ) != PROPHANDLING_NO_ERROR )
{
printf( "Failed to create callback object. Result: %s\n", DMR_ErrorCodeToString( result ) );
return;
}
if( ( result = OBJ_AttachCallback( hPropImageRequestTimeout_ms, hCallback ) ) == PROPHANDLING_NO_ERROR )
{
// provoke some callbacks by modifying the properties we just registered callbacks for.
// Whenever one of this features is changed in any way the previously attached callback
// handler will be called.
for( i = 0; i < 30; i++ )
{
printf( "Provoking callback %d.\n", i + 1 );
setPropI( hPropImageRequestTimeout_ms, i, 12345 );
}
if( ( result = OBJ_DetachCallback( hPropImageRequestTimeout_ms, hCallback ) ) != PROPHANDLING_NO_ERROR )
{
printf( "Failed to detach callback to property. Result: %s\n", DMR_ErrorCodeToString( result ) );
}
}
else
{
printf( "Failed to attach callback to property. Result: %s\n", DMR_ErrorCodeToString( result ) );
}
if( ( result = OBJ_DeleteCallback( hCallback ) ) != PROPHANDLING_NO_ERROR )
{
printf( "Failed to delete callback object. Result: %s\n", DMR_ErrorCodeToString( result ) );
}
hCallback = 0;
// now verify that the callbacks have actually been executed by displaying the amount of money left in the wallet
if( handbag.wallet_.euros_ < 2.14 )
{
printf( "The callback spent some of my money. I got %.2f left.\n", handbag.wallet_.euros_ );
}
}
//-----------------------------------------------------------------------------
int main( int argc, char* argv[] )
//-----------------------------------------------------------------------------
{
HDMR hDMR = INVALID_ID;
HDRV hDrv = INVALID_ID;
HDEV hDev = INVALID_ID;
unsigned int deviceCount = 0;
unsigned int i = 0;
HOBJ hPropSerial = INVALID_ID;
char* pStringBuffer = NULL;
unsigned int deviceNumber = 0;
// get rid of warnings
( void )argc;
( void )argv;
// try to initialise the library.
if( ( result = DMR_Init( &hDMR ) ) != DMR_NO_ERROR )
{
printf( "DMR_Init failed (code: %d)\n", result );
END_APPLICATION;
}
if( ( result = DMR_GetDeviceCount( &deviceCount ) ) != DMR_NO_ERROR )
{
printf( "DMR_GetDeviceCount failed (code: %d(%s))\n", result, DMR_ErrorCodeToString( result ) );
END_APPLICATION;
}
if( deviceCount == 0 )
{
printf( "No %s compliant device detected.\n", PRODUCT_NAME );
END_APPLICATION;
}
printf( "%d %s compliant devices detected.\n", deviceCount, PRODUCT_NAME );
for( i = 0; i < deviceCount; i++ )
{
// try to get access to the device
if( ( result = DMR_GetDevice( &hDev, dmdsmSerial, "*", i, '*' ) ) != DMR_NO_ERROR )
{
printf( "DMR_GetDevice(%d) failed (code: %d(%s))\n", i, result, DMR_ErrorCodeToString( result ) );
END_APPLICATION;
}
if( ( hPropSerial = getDeviceProp( hDev, "Serial" ) ) == INVALID_ID )
{
printf( "Failed to obtain device serial property for device %d.\n", i );
continue;
}
getStringValue( hPropSerial, &pStringBuffer, 0 );
printf( "[%d]: %s.\n", i, pStringBuffer );
free( pStringBuffer );
}
printf( "Please enter the number in front of the listed device followed by [ENTER] to open it: " );
deviceNumber = getIntValFromSTDIn();
// try to get access to the selected device
if( ( result = DMR_GetDevice( &hDev, dmdsmSerial, "*", deviceNumber, '*' ) ) != DMR_NO_ERROR )
{
printf( "DMR_GetDevice(%d) failed (code: %d(%s))\n", deviceNumber, result, DMR_ErrorCodeToString( result ) );
printf( "DMR_Close: %d\n", DMR_Close() );
END_APPLICATION;
}
// try to initialise this device
if( ( result = DMR_OpenDevice( hDev, &hDrv ) ) != DMR_NO_ERROR )
{
printf( "DMR_OpenDevice failed (code: %d)\n", result );
printf( "DMR_Close: %d\n", DMR_Close() );
END_APPLICATION;
}
checkCallbackCreation( hDrv );
printf( "DMR_CloseDevice: %d\n", DMR_CloseDevice( hDrv, hDev ) );
printf( "DMR_Close: %d\n", DMR_Close() );
END_APPLICATION;
}
TDMR_ERROR
Errors reported by the device manager.
Definition mvDriverBaseEnums.h:2601
@ DMR_NO_ERROR
The function call was executed successfully.
Definition mvDriverBaseEnums.h:2603
@ dmdsmSerial
Searches for a device with a certain serial number.
Definition mvDeviceManager.h:528
MVDMR_API TDMR_ERROR DMR_CALL DMR_GetDeviceCount(unsigned int *pDevCnt)
Receives the number of devices recognized by this interface.
Definition mvDeviceManager.cpp:1466
MVDMR_API TDMR_ERROR DMR_CALL DMR_Close(void)
Frees internal data structures and decreases the usage counter for this library.
Definition mvDeviceManager.cpp:1265
MVDMR_API TDMR_ERROR DMR_CALL DMR_CloseDevice(HDRV hDrv, HDEV hDev)
Closes a device.
Definition mvDeviceManager.cpp:1585
MVDMR_API TDMR_ERROR DMR_CALL DMR_Init(HDMR *pHDmr)
Initialises the library.
Definition mvDeviceManager.cpp:1137
MVDMR_API const char *DMR_CALL DMR_ErrorCodeToString(int errorCode)
Returns a string representation of a given error code.
Definition mvDeviceManager.cpp:5383
MVDMR_API TDMR_ERROR DMR_CALL DMR_OpenDevice(HDEV hDev, HDRV *pHDrv)
Initialises a device.
Definition mvDeviceManager.cpp:1516
MVDMR_API TDMR_ERROR DMR_CALL DMR_GetDevice(HDEV *pHDev, TDMR_DeviceSearchMode searchMode, const char *pSearchString, unsigned int devNr, char wildcard)
Tries to locate a certain device in the system which matches the input criteria.
Definition mvDeviceManager.cpp:1379
void * CallbackHandle
A type to create a unique identifier for a callback.
Definition mvPropHandlingDatatypes.h:894
const int INVALID_ID
A constant to check for an invalid ID returned from the property handling module.
Definition mvPropHandlingDatatypes.h:62
TPROPHANDLING_ERROR
Error codes of the module handling everything related to properties.
Definition mvPropHandlingDatatypes.h:382
MVDMR_API TPROPHANDLING_ERROR DMR_CALL OBJ_CreateCallback(TCallbackType type, CBOBJChanged pMeth, void *pUserData, CallbackHandle *phCallback)
Creates a new callback object that can be bound to one or multiple features.
Definition ObjectHandling.cpp:541
MVDMR_API TPROPHANDLING_ERROR DMR_CALL OBJ_AttachCallback(HOBJ hObj, CallbackHandle hCallback)
Attaches a previously created callback to a feature.
Definition ObjectHandling.cpp:612
MVDMR_API TPROPHANDLING_ERROR DMR_CALL OBJ_DeleteCallback(CallbackHandle hCallback)
Deletes a callback object.
Definition ObjectHandling.cpp:586
MVDMR_API TPROPHANDLING_ERROR DMR_CALL OBJ_DetachCallback(HOBJ hObj, CallbackHandle hCallback)
Detaches a previously created callback to a feature.
Definition ObjectHandling.cpp:640
@ PROPHANDLING_NO_ERROR
The operation has been executed successfully.
Definition mvPropHandlingDatatypes.h:384
@ ctOnChanged
Execute callback whenever this component has been modified.
Definition mvPropHandlingDatatypes.h:133