ID Number: Q72019
3.00
WINDOWS
docerr
Summary:
SYMPTOMS
When linking a application or a dynamic-link library (DLL) for the
Microsoft Windows environment, the Microsoft linker produces the
following error message:
error L2029: 'CHANGESELECTOR' : unresolved external
CAUSE
The program calls the ChangeSelector function. This function was
named PrestoChangoSelector in the kernel and in the LIBW.LIB
library. It was named ChangeSelector in the WINDOWS.H header file,
in the Microsoft Windows Software Development Kit (SDK)
documentation, and in the Windows SDK on-line help files.
RESOLUTION
Modify the code to call PrestoChangoSelector instead of
ChangeSelector. Add the following prototype to code compiled using
the WINDOWS.H header file from version 3.0 of the Windows SDK:
WORD PrestoChangoSelector(WORD, WORD);
More Information:
The documentation for ChangeSelector on page 4-24 of the "Microsoft
Windows Software Development Kit Reference--Volume 1" for Windows 3.0
is incorrect. The order of the parameters is reversed. This error has
been corrected in the documentation for PrestoChangoSelector on pages
750 and 751 of the "Microsoft Windows Software Development Kit:
Programmer's Reference, Volume 2: Functions" manual for Windows 3.1.
The following code fragment demonstrates how to change a data selector
into a code selector. The following code should be used only in a DLL
and it should be used only when absolutely necessary as in a Windows-
hosted programming environment. Directly manipulating selectors
violates preferred Windows programming practice.
Note: This code assumes that the WORD variable DATA_SELECTOR is the
selector for a block of data; in other words, an application called
GlobalAlloc to allocate a block of memory and stored the returned
handle (selector) in the DATA_SELECTOR variable.
WORD PrestoChangoSelector(WORD, WORD);
#include "windows.h"
...
WORD wCopyOfDataSelector;
WORD wSelectorToCode;
...
// When the AllocSelector function is called with a valid selector,
// the function copies the information associated with the selector to
// a new location in the descriptor table used by Windows, and returns
// this new location. Therefore, wCopyOfDataSelector is a second entry
// in the descriptor table that points to the globally allocated
// memory block.
if (wCopyOfDataSelector = AllocSelector(DATA_SELECTOR))
{
// PrestoChangoSelector toggles the bit in the descriptor table
// that specifies whether a block of memory is code or data.
// Therefore, wSelectorToCode is a modified version of
// wCopyOfDataSelector.
if (wSelectorToCode = PrestoChangoSelector(DATA_SELECTOR,
wCopyOfDataSelector))
{
... // call code pointed to by wSelectorToCode
if (FreeSelector(wCopyOfDataSelector))
return FALSE; // selector not freed
return TRUE; // everything worked!
}
}
WARNING: A selector created with the AllocSelector function is not
part of the Windows global arena and is not updated if memory movement
occurs. This could invalidate the new selector and terminate the
program with a general protection violation (GP-fault, Unrecoverable
Application Error, or UAE). The application can prevent memory from
moving by calling the GlobalFix function to fix the memory block in
the address space.
Additional reference words: 3.00