I'm trying to debug an error in some managed code related to timezones when a P/Invoke is throwing a native access violation exception. To make sure it's not something with the platform itself I decided to do the same in native code first to ensure that it's not some platform limitation or bug. Surprisingly I didn't readily find any sample code for doing it, so here's my contribution to the community at large. It uses dynamic loading (and it doesn't make sure that the function loads succeed, so you might want to add error checking if you actually intend to use this):
#include <windows.h>
typedef void (*INITCITYDB)(void);
typedef void (*UNINITCITYDB)(void);
typedef void (*LOADTZDATA)(void);
typedef void (*FREETZDATA)(void);
typedef int (*GETNUMZONES)(void);
typedef void * (*GETTZDATABYOFFSET)(int, int*);
typedef void * (*GETTZDATA)(int);
struct TZData
{
TCHAR *Name;
TCHAR *ShortName;
TCHAR *DSTName;
int GMTOffset;
int DSTOffset;
};
int _tmain(int argc, _TCHAR* argv[])
{
TZData *pTZ = NULL;
int index;
// load the library
HINSTANCE hLib = LoadLibrary(_T("CityDB.dll"));
// load the CityDB functions
INITCITYDB InitCityDB = (INITCITYDB)GetProcAddress(
hLib, _T("InitCityDb"));
UNINITCITYDB UninitCityDB = (UNINITCITYDB)GetProcAddress(
hLib, _T("UninitCityDb"));
LOADTZDATA ClockLoadAllTimeZoneData = (LOADTZDATA)GetProcAddress(
hLib, _T("ClockLoadAllTimeZoneData"));
FREETZDATA ClockFreeAllTimeZoneData = (FREETZDATA)GetProcAddress(
hLib, _T("ClockFreeAllTimeZoneData"));
GETNUMZONES ClockGetNumTimezones = (GETNUMZONES)GetProcAddress(
hLib, _T("ClockGetNumTimezones"));
GETTZDATABYOFFSET ClockGetTimeZoneDataByOffset =
(GETTZDATABYOFFSET)GetProcAddress(hLib, _T("ClockGetTimeZoneDataByOffset"));
GETTZDATA ClockGetTimeZoneData = (GETTZDATA)GetProcAddress(
hLib, _T("ClockGetTimeZoneData"));
// Init the library
InitCityDB();
// load the TZ data
ClockLoadAllTimeZoneData();
// find out how many zones are defined
int zoneCount = ClockGetNumTimezones();
// interate through them all
for(int zone = 0 ; zone < zoneCount ; zone++)
{
// these are pointers to a timezone data struct
pTZ = (TZData*)ClockGetTimeZoneDataByOffset(zone, &index);
}
// unload the TZ data
ClockFreeAllTimeZoneData();
// uninit the library
UninitCityDB();
return 0;
}