我有许多工作模拟类可以取代对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)
的实现?
答案 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
。