This is article number 5 in a series of articles about monitoring batteries in Windows XP. In Windows XP: Monitoring Batteries in C Sharp I presented a C# class that can be used to get information about the system batteries. In Windows XP: Monitoring Batteries in C++ I presented a similar C++ class. Then in Windows XP: Displaying Battery Status in C Sharp I used the C# class in a C# application. In this article, we will look at modifying the C# app to use the C++ class delivered as a DLL.
The C++ class is exposed to C# through C wrapper functions. To use the DLL, we need to P/Invoke, so the first step is to add extern method definitions:
        [DllImport("Win32Battery.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        extern static IntPtr InitWIN32_Battery();
        [DllImport("Win32Battery.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode, SetLastError = true)]
             extern static void DeinitWIN32_Battery(IntPtr Batts);
        [DllImport("Win32Battery.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode, SetLastError = true)]
             static extern void WIN32_Battery_Refresh(IntPtr Batts);
        [DllImport("Win32Battery.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode, SetLastError = true)]
             static extern int WIN32_Battery_GetPercentChargeRemaining(IntPtr Batts, int BatteryNumber);
        [DllImport("Win32Battery.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode, SetLastError = true)]
             static extern int WIN32_Battery_NumberOfBatteries(IntPtr Batts);
 
 
The function InitWIN2_Battery() returns a HANDLE, which will be used in C# as an IntPtr. The C# class needs to store this HANDLE for future reference:
        IntPtr hBatteries;
 
The constructor and destructor will call InitWIN32_Battery() and DeinitWIN32_Battery():
        public Win32_Battery()
        {
            try
            {
                hBatteries = IntPtr.Zero;
                hBatteries = InitWIN32_Battery();
            }
            catch (SystemException)
            {
                System.Windows.Forms.MessageBox.Show("Error initializing batteries");
            }
        }
        ~Win32_Battery()
        {
            DeinitWIN32_Battery(hBatteries);
            hBatteries = IntPtr.Zero;
        }
 
And the rest of the functions are simply wrappers for the other C functions:
        public void Refresh()
        {
            try
            {
                WIN32_Battery_Refresh(hBatteries);
            }
            catch (SystemException)
            {
                System.Windows.Forms.MessageBox.Show("Error getting battery information");
            }
        }
        public int NumberOfBatteries()
        {
            return WIN32_Battery_NumberOfBatteries(hBatteries);
        }
        public int GetPercentChargeRemaining(int BatteryNumber)
        {
            return WIN32_Battery_GetPercentChargeRemaining(hBatteries, BatteryNumber);
        }
 
With these changes, the C# application now uses the C++ DLL.
 
Copyright © 2010 – Bruce Eitman
All Rights Reserved