如何为按地址传递参数的Windows API调用编写测试双精度数

时间:2015-08-21 15:54:55

标签: c++ unit-testing pointers mocking

我有许多工作模拟类可以取代对Windows API的实际调用。但是,在使用FormatMessageW标志时,我正在努力为使用FORMAT_MESSAGE_ALLOCATE_BUFFER的函数组合一些东西。

使用FormatMessageW函数时,我首先按如下方式声明缓冲区:

wchar_t * buffer = nullptr;

然后我按地址传递缓冲区作为lpBuffer参数(期望类型为LPWSTR):

reinterpret_cast<::LPWSTR>(&buffer)

Windows API函数将自动创建一个正确大小的缓冲区。

我继续使用缓冲区删除换行符,从宽字符转换为多字节字符等。

为了完全单元测试清理输出缓冲区,我试图通过让函数简单地返回一个预定义的字符串(它将是模拟对象的一个​​成员)来模拟FormatMessageW调用。 / p>

为了简化问题,以下代码尝试复制我的问题:

// represents my mock class
class mocker
{

public:
    // takes a wchar_t pointer and attempts to reassign it
    int mockFunction(wchar_t * buffer)
    {
        // assigns local copy of wchar_t pointer!
        buffer = &message[0];

        return message.length();
    }

protected:

    std::wstring message = L"test";
};

// test code
mocker mocking;
wchar_t * buffer = nullptr;
auto size = mocking.mockFunction(&buffer);

// at this point buffer is still null
// but I want the buffer to point to L"test"

有没有办法实现我的目标,即将指针重定向到现有std::wstring而不改变int mockFunction(wchar_t * buffer)的实现?

2 个答案:

答案 0 :(得分:1)

您所追求的可能是使用FORMAT_MESSAGE_ALLOCATE_BUFFER选项的此方法。您可以在此处找到此选项的示例使用:

https://support.microsoft.com/en-us/kb/256348

它看起来如下:

HLOCAL pBuffer;   // Buffer to hold the textual error description.
// .... 
ret = FormatMessage( 
                FORMAT_MESSAGE_ALLOCATE_BUFFER | // Function will handle memory allocation.
                FORMAT_MESSAGE_FROM_HMODULE | // Using a module's message table.
                FORMAT_MESSAGE_IGNORE_INSERTS, 
                hInst, // Handle to the DLL.
                dwErrorMsgId, // Message identifier.
                MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language.
                (LPTSTR)&pBuffer, // Buffer that will hold the text string.
                ERRMSGBUFFERSIZE, // Allocate at least this many chars for pBuffer.
                NULL // No insert values.
                    );

HLOCAL定义为typedef HANDLE HLOCAL;HANDLE定义为typedef void *HANDLE;。那么在上面的示例&pBuffer中返回指向指针的指针,然后将其转换为LPTSTR,它也是一个指针。在FormatMessage内部,检查是否使用了FORMAT_MESSAGE_ALLOCATE_BUFFER,如果是,那么buffer参数就像那样(可能),HLOCAL* pToAllocBuffer = reinterpret_cast<HLOCAL*>(buffer)以及稍后*pToAllocBuffer = LocalAlloc(.....)一样投射。

所以,在你的mockFunction中你也必须做这样丑陋的演员,首先:

wchar_t * buffer = nullptr;
auto size = mocking.mockFunction(reinterpret_cast<wchar_t * >(&buffer));

mockFunction内部:

wchar_t ** buffer = reinterpret_cast<wchar_t ** >(buffer);

现在您可以将内存分配给缓冲区:

*buffer = [HERE YOUR ALLOCATION];

不要这样做:

  

//分配wchar_t指针的本地副本......

如果您要分配本地副本,它将在函数返回时释放,您必须使用new

答案 1 :(得分:0)

感谢 marcinj的回答,我通过使用以下实现来实现我的目标:

int mockFunction(wchar_t * buffer)
{
    wchar_t ** bufferPointer = reinterpret_cast<wchar_t **>(buffer);
    *bufferPointer = &message[0];

    return message.length();
}

当我将其实现到工作模拟类中时,我将wchar_t *替换为LPWSTR