1

我有这个代码,我在 Windows 中没有经验:

#include <windows.h>
#include <stdio.h>


   typedef BOOL (WINAPI *P_GDFSE)(LPCTSTR, PULARGE_INTEGER, 
                                  PULARGE_INTEGER, PULARGE_INTEGER);

   void main (int argc, char **argv)
   {
      BOOL  fResult;

      char  *pszDrive  = NULL,
             szDrive[4];

      DWORD dwSectPerClust,
            dwBytesPerSect,
            dwFreeClusters,
            dwTotalClusters;

      P_GDFSE pGetDiskFreeSpaceEx = NULL;

      unsigned __int64 i64FreeBytesToCaller,
                       i64TotalBytes,
                       i64FreeBytes;


      if (argc != 2)
      {
         printf ("usage:  %s <drive|UNC path>\n", argv[0]);
         printf ("\texample:  %s C:\\\n", argv[0]);
         return;
      }

      pszDrive = argv[1];

      if (pszDrive[1] == ':')
      {
         szDrive[0] = pszDrive[0];
         szDrive[1] = ':';
         szDrive[2] = '\\';
         szDrive[3] = '\0';

         pszDrive = szDrive;
      }

     // FIRST ERROR  kernel32.dll
      pGetDiskFreeSpaceEx = (P_GDFSE)GetProcAddress (
                               GetModuleHandle ("kernel32.dll"),
                                              "GetDiskFreeSpaceExA");
       // SECOND ERROR pszDrive
      if (pGetDiskFreeSpaceEx)
      {
         fResult = pGetDiskFreeSpaceEx (pszDrive,
                                 (PULARGE_INTEGER)&i64FreeBytesToCaller,
                                 (PULARGE_INTEGER)&i64TotalBytes,
                                 (PULARGE_INTEGER)&i64FreeBytes);
         if (fResult)
         {
            printf ("\n\nGetDiskFreeSpaceEx reports\n\n");
            printf ("Available space to caller = %I64u MB\n",
                    i64FreeBytesToCaller / (1024*1024));
            printf ("Total space               = %I64u MB\n",
                    i64TotalBytes / (1024*1024));
            printf ("Free space on drive       = %I64u MB\n",
                    i64FreeBytes / (1024*1024));
         }
      }
      else
      {
         // ERROR 3 pszDrive
         fResult = GetDiskFreeSpace (pszDrive, 
                                     &dwSectPerClust,
                                     &dwBytesPerSect, 
                                     &dwFreeClusters,
                                     &dwTotalClusters);
         if (fResult)
         {
            /* force 64-bit math */ 
            i64TotalBytes = (__int64)dwTotalClusters * dwSectPerClust *
                              dwBytesPerSect;
            i64FreeBytes = (__int64)dwFreeClusters * dwSectPerClust *
                              dwBytesPerSect;

            printf ("GetDiskFreeSpace reports\n\n");
            printf ("Free space  = %I64u MB\n", 
                    i64FreeBytes / (1024*1024));
            printf ("Total space = %I64u MB\n", 
                    i64TotalBytes / (1024*1024));
         }
      }

      if (!fResult)
         printf ("error: %lu:  could not get free space for \"%s\"\n",
                 GetLastError(), argv[1]);
   }

我收到了这些错误(visual studio 2010 终极版):

在 kernel32.dll:

pGetDiskFreeSpaceEx = (P_GDFSE)GetProcAddress (GetModuleHandle ("kernel32.dll"), "GetDiskFreeSpaceExA");

错误:const char* 类型的参数与“LPCWSTR”类型的参数不兼容

在 pszDrive:

fResult = pGetDiskFreeSpaceEx (pszDrive,
                                 (PULARGE_INTEGER)&i64FreeBytesToCaller,
                                 (PULARGE_INTEGER)&i64TotalBytes,
                                 (PULARGE_INTEGER)&i64FreeBytes);

错误:char* 类型的参数与“LPCTSTR”类型的参数不兼容

在 pszDrive:

 fResult = GetDiskFreeSpace (pszDrive, 
                                     &dwSectPerClust,
                                     &dwBytesPerSect, 
                                     &dwFreeClusters,
                                     &dwTotalClusters);

错误:char* 类型的参数与“LPCWSTR”类型的参数不兼容

多谢

4

3 回答 3

4

最简单的解决方案是将项目设置更改为多字节字符集。

为此,在解决方案资源管理器中右键单击项目,选择属性。在属性对话框的左侧窗格中选择常规。找到字符集并将其更改为“使用多字节字符集”。

但是,如果您要进行大量 Windows 编程,您应该习惯 Unicode。基本上这意味着使用 wchar_t(或 TCHAR)而不是 char,包括在常量字符串中:

      pGetDiskFreeSpaceEx = (P_GDFSE)GetProcAddress (
                                          GetModuleHandle (L"kernel32.dll"),
                                          "GetDiskFreeSpaceExW");

在这种情况下,正如 Adam 正确指出的那样,您还需要将函数名称从 A 版本更改为 W 版本。

于 2012-10-22T23:36:21.943 回答
1

更改您的代码以更加TCHAR了解,因为当您像您一样将 Ansi 和 Unicode 代码混合在一起时,这是 Win2 API 所期望的:

#include <windows.h> 
#include <stdio.h> 
#include <tchar.h>

typedef BOOL (WINAPI *P_GDFSE)(LPCTSTR, PULARGE_INTEGER,  
                              PULARGE_INTEGER, PULARGE_INTEGER); 

void _tmain (int argc, TCHAR **argv) 
{ 
    BOOL  fResult; 

    TCHAR *pszDrive = NULL,
          szDrive[4]; 

    DWORD dwSectPerClust, 
          dwBytesPerSect, 
          dwFreeClusters, 
          dwTotalClusters; 

    P_GDFSE pGetDiskFreeSpaceEx = NULL; 

    unsigned __int64 i64FreeBytesToCaller, 
                     i64TotalBytes, 
                     i64FreeBytes; 


    if (argc != 2) 
    { 
        _tprintf (_T("usage:  %s <drive|UNC path>\n"), argv[0]); 
        _tprintf (_T("\texample:  %s C:\\\n"), argv[0]); 
        return; 
    } 

    pszDrive = argv[1]; 

    if (pszDrive[1] == TEXT(':')) 
    { 
        _stprintf(szDrive, _T("%s:\\"), pszDrive[0]); 
        pszDrive = szDrive; 
    } 

    // FIRST ERROR  kernel32.dll 
    pGetDiskFreeSpaceEx = (P_GDFSE) GetProcAddress ( 
                           GetModuleHandle (TEXT("kernel32.dll")), 
                                          #ifdef UNICODE
                                          "GetDiskFreeSpaceExW"); 
                                          #else
                                          "GetDiskFreeSpaceExA"); 
                                          #endif
                           );

    // SECOND ERROR pszDrive 
    if (pGetDiskFreeSpaceEx) 
    { 
        fResult = pGetDiskFreeSpaceEx (pszDrive, 
                             (PULARGE_INTEGER)&i64FreeBytesToCaller, 
                             (PULARGE_INTEGER)&i64TotalBytes, 
                             (PULARGE_INTEGER)&i64FreeBytes); 
        if (fResult) 
        { 
            _tprintf (_T("\n\nGetDiskFreeSpaceEx reports\n\n")); 
            _tprintf (_T("Available space to caller = %I64u MB\n"), 
                i64FreeBytesToCaller / (1024*1024)); 
            _tprintf (_T("Total space               = %I64u MB\n"), 
                i64TotalBytes / (1024*1024)); 
            _tprintf (_T("Free space on drive       = %I64u MB\n"), 
                i64FreeBytes / (1024*1024)); 
        } 
    } 
    else 
    { 
        // ERROR 3 pszDrive 
        fResult = GetDiskFreeSpace (pszDrive,  
                                 &dwSectPerClust, 
                                 &dwBytesPerSect,  
                                 &dwFreeClusters, 
                                 &dwTotalClusters); 
        if (fResult) 
        { 
            /* force 64-bit math */  
            i64TotalBytes = (__int64)dwTotalClusters * dwSectPerClust * 
                          dwBytesPerSect; 
            i64FreeBytes = (__int64)dwFreeClusters * dwSectPerClust * 
                          dwBytesPerSect; 

            _tprintf (_T("GetDiskFreeSpace reports\n\n")); 
            _tprintf (_T("Free space  = %I64u MB\n"),  
                i64FreeBytes / (1024*1024)); 
            _tprintf (_T("Total space = %I64u MB\n"),  
                i64TotalBytes / (1024*1024)); 
        } 
    } 

    if (!fResult) 
        _tprintf (_T("error: %lu:  could not get free space for \"%s\"\n"), 
             GetLastError(), argv[1]); 
} 

否则,由于您使用UNICODE启用编译,只需编写仅 Unicode 代码:

#include <windows.h> 
#include <stdio.h> 

typedef BOOL (WINAPI *P_GDFSE)(LPCWSTR, PULARGE_INTEGER,  
                              PULARGE_INTEGER, PULARGE_INTEGER); 

void wmain (int argc, wchar_t **argv) 
{ 
    BOOL  fResult; 

    wchar_t *pszDrive = NULL,
          szDrive[4]; 

    DWORD dwSectPerClust, 
          dwBytesPerSect, 
          dwFreeClusters, 
          dwTotalClusters; 

    P_GDFSE pGetDiskFreeSpaceEx = NULL; 

    unsigned __int64 i64FreeBytesToCaller, 
                     i64TotalBytes, 
                     i64FreeBytes; 


    if (argc != 2) 
    { 
        wprintf (L"usage:  %s <drive|UNC path>\n", argv[0]); 
        wprintf (L"\texample:  %s C:\\\n", argv[0]); 
        return; 
    } 

    pszDrive = argv[1]; 

    if (pszDrive[1] == L':') 
    { 
        _stprintf(szDrive, _T("%s:\\"), pszDrive[0]); 
        pszDrive = szDrive; 
    } 

    // FIRST ERROR  kernel32.dll 
    pGetDiskFreeSpaceEx = (P_GDFSE) GetProcAddress ( 
                           GetModuleHandle (TEXT("kernel32.dll")), 
                                          "GetDiskFreeSpaceExW"
                           ); 
    // SECOND ERROR pszDrive 
    if (pGetDiskFreeSpaceEx) 
    { 
        fResult = pGetDiskFreeSpaceEx (pszDrive, 
                             (PULARGE_INTEGER)&i64FreeBytesToCaller, 
                             (PULARGE_INTEGER)&i64TotalBytes, 
                             (PULARGE_INTEGER)&i64FreeBytes); 
        if (fResult) 
        { 
            wprintf (L"\n\nGetDiskFreeSpaceEx reports\n\n"); 
            wprintf (L"Available space to caller = %I64u MB\n", 
                i64FreeBytesToCaller / (1024*1024)); 
            wprintf (L"Total space               = %I64u MB\n", 
                i64TotalBytes / (1024*1024)); 
            wprintf (L"Free space on drive       = %I64u MB\n", 
                i64FreeBytes / (1024*1024)); 
        } 
    } 
    else 
    { 
        // ERROR 3 pszDrive 
        fResult = GetDiskFreeSpace (pszDrive,  
                                 &dwSectPerClust, 
                                 &dwBytesPerSect,  
                                 &dwFreeClusters, 
                                 &dwTotalClusters); 
        if (fResult) 
        { 
            /* force 64-bit math */  
            i64TotalBytes = (__int64)dwTotalClusters * dwSectPerClust * 
                          dwBytesPerSect; 
            i64FreeBytes = (__int64)dwFreeClusters * dwSectPerClust * 
                          dwBytesPerSect; 

            wprintf (L"GetDiskFreeSpace reports\n\n"); 
            wprintf (L"Free space  = %I64u MB\n",  
                i64FreeBytes / (1024*1024)); 
            wprintf (L"Total space = %I64u MB\n",  
                i64TotalBytes / (1024*1024)); 
        } 
    } 

    if (!fResult) 
        wprintf (L"error: %lu:  could not get free space for \"%s\"\n", 
             GetLastError(), argv[1]); 
} 
于 2012-10-23T01:56:24.283 回答
0

您显然是在UNICODE模式下编译。更改以下内容:

void _tmain (int argc, TCHAR **argv)

  TCHAR  *pszDrive  = NULL,
         szDrive[4];

那应该会让你走得更远。有关更多信息,请参阅以下问题:C++ 中的 _tmain() 和 main() 有什么区别?

于 2012-10-22T23:13:13.503 回答