编辑GCC头文件可以吗?

Is it OK to Edit GCC Header Files?

本文关键字:文件 GCC 编辑      更新时间:2023-10-16

我试图从MSDN与GCC在Windows 7上编译一些示例代码(请忽略使用goto和可怕的格式;这不是我的代码):

#include <stdio.h>
#include <windows.h>
typedef struct _TOKEN_ELEVATION {
    DWORD TokenIsElevated;
} TOKEN_ELEVATION, *PTOKEN_ELEVATION;
BOOL IsProcessElevated()
{
BOOL fIsElevated = FALSE;
DWORD dwError = ERROR_SUCCESS;
HANDLE hToken = NULL;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
{
    dwError = GetLastError();
    goto Cleanup;
}
TOKEN_ELEVATION elevation;
DWORD dwSize;
if (!GetTokenInformation(hToken, TokenElevation, &elevation,
    sizeof(elevation), &dwSize))
{
    dwError = GetLastError();
    goto Cleanup;
}
fIsElevated = elevation.TokenIsElevated;
Cleanup:
if (hToken)
{
    CloseHandle(hToken);
    hToken = NULL;
}
if (ERROR_SUCCESS != dwError)
{
    throw dwError;
}
return fIsElevated;
}
int main()
{
try
{
    if (IsProcessElevated())
        wprintf (L"Process is elevatedn");
    else
        wprintf (L"Process is not elevatedn");
}
catch (DWORD dwError)
{
    wprintf(L"IsProcessElevated failed w/err %lun", dwError);
}
}

我一直得到错误TokenElevation was not declared in this scope。在试图弄清楚时,我看到TOKEN_INFORMATION_CLASS结构的TokenElevation成员位于两个#ifdef标签之间:

typedef enum _TOKEN_INFORMATION_CLASS {
TokenUser=1,
TokenGroups,
TokenPrivileges,
TokenOwner,
TokenPrimaryGroup,
TokenDefaultDacl,
TokenSource,
TokenType,
TokenImpersonationLevel,
TokenStatistics,
TokenRestrictedSids,
TokenSessionId,
TokenGroupsAndPrivileges,
TokenSessionReference,
TokenSandBoxInert,
TokenAuditPolicy,
TokenOrigin,
//#if (_WIN32_WINNT >= 0x0600)
TokenElevationType,
TokenLinkedToken,
TokenElevation,
TokenHasRestrictions,
TokenAccessInformation,
TokenVirtualizationAllowed,
TokenVirtualizationEnabled,
TokenIntegrityLevel,
TokenUIAccess,
TokenMandatoryPolicy,
TokenLogonSid,
//#endif
MaxTokenInfoClass
} TOKEN_INFORMATION_CLASS;

我把这些注释掉了,代码编译后没有错误或警告。我的问题实际上是两个问题。这是一个更好的方法(在我的代码中定义一些东西?),从长远来看,编辑头文件会伤害我吗?

编辑头文件会造成伤害,因为您的代码不再是基于您仅仅依赖的外部库构建的。相反,您已经有效地使外部代码成为项目的一部分,现在您必须像管理项目中的其他源代码一样管理它。例如,你应该把它保存在你的版本控制系统中。

是的,有一个更好的方法:你可以简单地定义_WIN32_WINNT,因为Windows代码期望它被定义。Visual Studio项目默认定义了这个宏,但在Windows上使用gcc构建时必须手动执行。

本页定义了每个Windows版本的值

是的,你可以编辑和修改GCC头文件。

请注意,当GCC升级时,您的更改可能会丢失。您必须将更改合并到较新的头文件中。

由于这个原因,一般的经验法则是不要修改编译器头文件。

编辑1:
此外,如果您共享代码,则需要让客户端对GCC头文件进行与您相同的修改。一些客户端可能不希望更改其编译器头文件。同样的规则也适用于其他人在同一项目上的工作。

另外,您的更改会影响将来的项目吗?将来的项目也可以使用GCC头文件。

您可以修改它们,但这通常是一个坏主意,因为它将使您的编译难以重复。

在这种特殊情况下,正确的解决方案是将_WIN32_WINNT定义为0x0600或更高。这个宏用于指定您要瞄准的Windows版本,显然您要瞄准的至少是版本6,否则您将无法使用此值。Windows SDK头文件使用该宏来有条件地包含每个版本Windows中可用的声明,因此,例如,您不能在打算在Windows 7中运行的程序中使用Windows 8中的函数/字段/enum值。

所以只要把-D_WIN32_WINNT=0x0600添加到你的编译命令中,不要管头文件…