WinAPI混淆功能参数

时间:2017-07-12 18:16:30

标签: c++ pointers winapi parameters

相关功能的API参考:RmStartSession

代码:

#include <Windows.h>
#include <RestartManager.h>

/*
DWORD WINAPI
RmStartSession(
    _Out_ DWORD *pSessionHandle,
    _Reserved_ DWORD dwSessionFlags,
    _Out_writes_(CCH_RM_SESSION_KEY + 1) WCHAR strSessionKey[]);
*/

int main(int /*argc*/, char** /*argv*/)
{
    WCHAR sessionKey[CCH_RM_SESSION_KEY + 1];

    // 1.
    DWORD *sessionOne = nullptr;
    auto returnCodeOne = RmStartSession(sessionOne, NULL, sessionKey); // = 160 ERROR_BAD_ARGUMENTS

    // 2.
    DWORD sessionTwo = 0xFFFFFFF;
    DWORD *pSessionHandleTwo = &sessionTwo;
    auto returnCodeTwo = RmStartSession(pSessionHandleTwo, NULL, sessionKey); // = 0 ERROR_SUCCESS

    // 3.
    DWORD sessionThree = 0xFFFFFFF;
    auto returnCodeThree = RmStartSession(&sessionThree, NULL, sessionKey); // = 0 ERROR_SUCCESS

    return 0;
}  

我花了一些时间才意识到为什么1.给了我一个BAD_ARGUMENTS错误,因为上面编译好的所有变种都是合法的语言结构。

问题是该函数实际上需要一个指向有效对象的指针,并且只是使用该指针来修改对象,而不是修改指针本身。因此,如果指针是nullptr,那么没有要修改的对象,该函数本身不会分配对象 (如果我的理解错误,请纠正我)

话虽如此,为什么定义的函数不能请求引用DWORD以明确它不能为空,是否有特定的理由在这里使用指针?
我错过了什么?

1 个答案:

答案 0 :(得分:1)

这个问题有两个答案:

  1. 这是一个C api,因此API编写者无法使用引用。

  2. 有一种想法认为使用输出值参数的引用是错误的API设计,并且应始终使用指针,即使这意味着传递nullptr将是一场灾难。

  3. 这个想法是基于参考的输出参数在呼叫站点真的很混乱。请查看以下代码:

    void foo() {
       my_struct val;
       bar(val);
    }
    
    void foo_alt() {
       my_struct val;
       bar_alt(&val);
    }
    

    乍一看,人们不希望bar在第一个例子中修改val,但有人会在第二个例子中怀疑它。

    通过仅查看调用站点来了解函数的作用是自我记录代码的基础,而可变引用通常会破坏它(除非它在函数名称中非常清楚)。