error C2065: 'GetFileSizeEx' : undeclared identifier

4107 ワード

今日、『Windows API開発の詳細——関数、インタフェース、プログラミングの実例』を勉強したところ、実例4.7で次のような問題に遭遇しました.
VC++6.0環境では、文:
if (!GetFileSizeEx(hFileRead,&liFileSize))
{
	printf("        :%d",GetLastError());
}

コンパイルエラー:
Compiling...
wr.cpp
D:\CWorkspaces\cpp\apilearn4\WR\wr.cpp(49) : error C2065: 'GetFileSizeEx' : undeclared identifier
Error executing cl.exe.
Creating browse info file...

WR.exe - 1 error(s), 0 warning(s)

MSDNを確認して、以下の要求を得ます.
 Windows NT/2000/XP: Included in Windows 2000 and later.   Windows 95/98/Me: Unsupported.   Header: Declared in Winbase.h; include Windows.h.   Library: Use Kernel32.lib.
私が使っているwin 7システムは、システム上で合致しており、引き続き資料を探しています...
ある人は言います:VC 6.0デフォルトのコンパイル環境はWINVER=0 x 0400、つまりWindows 95 andWindowsNT 4である.0以上で実行される、設定:
#define WINVER 0x0500
しかし、依然として問題を解決していない.
引き続き資料を探します...
VC6.0バンドのSDKにはこの関数の宣言はありません.使用する場合は、新しいSDKをインストールするか、Kernel 32から直接インストールすることができます.dllでGetProcAddressがGetFileSizeExの関数ポインタを取得して再呼び出す.
そこで2つ目の方法で解決しました.解決策は次のとおりです.
/*   GetFileSizeEx   */
HMODULE hModule=GetModuleHandle("kernel32.dll"); 
typedef BOOL (CALLBACK* GetFileSizeEx)(HANDLE,PLARGE_INTEGER);
GetFileSizeEx pGetFileSizeEx;    // Function pointer
pGetFileSizeEx=(GetFileSizeEx)GetProcAddress(hModule,"GetFileSizeEx"); 

if (!(*pGetFileSizeEx)(hFileRead,&liFileSize))
{
	printf("        :%d",GetLastError());
}

問題解決!
GetProcAddressの使い方については、(http://technet.microsoft.com/zh-cn/library/aa269780):
Processes explicitly linking to a DLL call GetProcAddress to obtain the address of an exported function in the DLL. You use the returned function pointer to call the DLL function.GetProcAddress takes as parameters the DLL module handle (returned by eitherLoadLibrary, AfxLoadLibrary, orGetModuleHandle), and either the name of the function you want to call or the function's export ordinal. Because you are calling the DLL function through a pointer and there is no compile-time type checking, make sure that the parameters to the function are correct so that you do not over step the memory allocated on the stack and cause an access violation. One way to ensure type safety is to look at the function prototypes of the exported functions and create matching typedefs for the function pointers. For example:
typedef UINT (CALLBACK* LPFNDLLFUNC1)(DWORD,UINT);
.
.
.
HINSTANCE hDLL;               // Handle to DLL
LPFNDLLFUNC1 lpfnDllFunc1;    // Function pointer
DWORD dwParam1;
UINT  uParam2, uReturnVal;

hDLL = LoadLibrary("MyDLL");
if (hDLL != NULL)
{
   lpfnDllFunc1 = (LPFNDLLFUNC1)GetProcAddress(hDLL,
                                           "DLLFunc1");
   if (!lpfnDllFunc1)
   {
      // handle the error
      FreeLibrary(hDLL);      
      return SOME_ERROR_CODE;
   }
   else
   {
      // call the function
      uReturnVal = lpfnDllFunc1(dwParam1, uParam2);
   }
}
How you specify the function you want when calling GetProcAddress depends on how the DLL was built. You can only obtain the export ordinal if the DLL you are linking to was built with a module definition (.DEF) file, and if the ordinals are listed with the functions in theEXPORTS section of the DLL's .DEF file. CallingGetProcAddress with an export ordinal, as opposed to the function name, is slightly faster if the DLL has many exported functions because the export ordinals serve as indexes into the DLL's export table. With an export ordinal,GetProcAddress can locate the function directly as opposed to comparing the specified name to the function names in the DLL's export table. However, you should callGetProcAddress with an export ordinal only if you have control over assigning the ordinals to the exported functions in the .DEF file.