我有许多工作的模拟类,它们代替了对Windows API的实际调用。但是,我在为使用FormatMessageW
标志时利用FORMAT_MESSAGE_ALLOCATE_BUFFER
的功能拼凑而成。
使用FormatMessageW
函数时,我首先声明缓冲区如下:
wchar_t * buffer = nullptr;
然后,我按地址作为
lpBuffer
参数传递缓冲区(预期类型为LPWSTR
):reinterpret_cast<::LPWSTR>(&buffer)
Windows API函数将自动创建正确大小的缓冲区。
我通过去除换行符,从宽字符转换为多字节字符等来进一步处理缓冲区。
为了完全对输出缓冲区的清理进行单元测试,我试图通过让函数简单地返回预定义的字符串(将成为模拟对象的成员)来模拟
FormatMessageW
调用。为了简化问题,以下代码尝试复制我的问题:
// 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)
的实现? 最佳答案
您所追求的可能是将此方法与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(.....)
。因此,在您的模拟函数中,您也必须首先进行此类丑陋的转换:
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
。