Änderungen an der Symboltabelle ereignisgesteuert erkennen
ADS-Geräte, die Symbolnamen unterstützen (SPS, NC, ...), legen die Symbolnamen in eine interne Tabelle ab. Dabei wird jedem Symbol ein Handle zugeordnet. Das Symbolhandle wird benötigt, um auf die Variablen zugreifen zu können (siehe auch Beispiel 9). Ändert sich die Symboltabelle, z. B. weil ein neues SPS-Programm in die Steuerung geschrieben wird, so müssen auch die Handles neu ermittelt werden. Wie Änderungen an der Symboltabelle erkannt werden können, zeigt das folgende Beispiel.
Download: sample12-c-ads-dll-detectsymbolchanges.zip
#include <iostream.h>
#include <windows.h>
#include <conio.h>
#include <winbase.h>
// ADS headers
#include "C:\TwinCAT\AdsApi\TcAdsDll\Include\TcAdsDef.h"
#include "C:\TwinCAT\AdsApi\TcAdsDll\Include\TcAdsApi.h"
void __stdcall SymbolChanged(AmsAddr*, AdsNotificationHeader*, unsigned long);
void main()
{
long nErr;
AmsAddr Addr;
PAmsAddr pAddr = &Addr;
ULONG hNotification;
AdsNotificationAttrib adsNotificationAttrib;
// Open communication port on the ADS router
AdsPortOpen();
nErr = AdsGetLocalAddress(pAddr);
if (nErr) cerr << "Error: AdsGetLocalAddress: " << nErr << '\n';
// Select Port: TwinCAT2 PLC1
pAddr->port = 801;
// Specify attributes of the notification
adsNotificationAttrib.cbLength = 1;
adsNotificationAttrib.nTransMode = ADSTRANS_SERVERONCHA;
adsNotificationAttrib.nMaxDelay = 5000000; // 500ms
adsNotificationAttrib.nCycleTime = 5000000; // 500ms
// Start notification for changes to the symbol table
nErr = AdsSyncAddDeviceNotificationReq(pAddr, ADSIGRP_SYM_VERSION, 0, &adsNotificationAttrib, SymbolChanged, NULL, &hNotification);
if (nErr) cerr << "Error: AdsSyncAddDeviceNotificationReq: " << nErr << '\n';
// Wait for a key-press from the user
_getch();
// Stop notification
nErr = AdsSyncDelDeviceNotificationReq(pAddr, hNotification);
if (nErr) cerr << "Error: AdsSyncDelDeviceNotificationReq: " << nErr << '\n';
// Close communication port
nErr = AdsPortClose();
if (nErr) cerr << "Error: AdsPortClose: " << nErr << '\n';
}
// Callback function
void __stdcall SymbolChanged(AmsAddr* pAddr, AdsNotificationHeader* pNotification, ULONG hUser)
{
cout << "Symboltabelle hat sich geändert!\n";
cout.flush();
}