如何为通过地址传递参数的Windows API调用编写测试双精度
How to write test doubles for Windows API calls that pass arguments by address
我有一些可用的模拟类来代替对Windows API的实际调用。然而,我正在努力为使用FORMAT_MESSAGE_ALLOCATE_BUFFER
标志时使用FormatMessageW
的功能组合一些东西。
当使用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
选项的此方法。您可以在这里找到该选项的示例用法:
内容如下:
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));
and inside mockFunction
:
wchar_t ** buffer = reinterpret_cast<wchar_t ** >(buffer);
现在你可以像这样分配内存给缓冲区:
*buffer = [HERE YOUR ALLOCATION];
不要这样做:
//分配wchar_t指针的本地副本…
如果你分配本地拷贝,它将在函数返回时被释放,你必须使用new
。
多亏了marcinj的回答,我能够通过使用以下实现实现我的目标:
int mockFunction(wchar_t * buffer)
{
wchar_t ** bufferPointer = reinterpret_cast<wchar_t **>(buffer);
*bufferPointer = &message[0];
return message.length();
}
当我在工作模拟类中实现这一点时,我将wchar_t *
替换为LPWSTR
。
- 使用Qt框架在c ++类中创建API调用
- 调用 Win32 API 函数时未定义的引用
- 程序在对mouse_event的 Windows API 调用中冻结
- 使用 Node.js N-API 调用 C 函数时,不会显示预期的输出
- 同时调用 ASIO 对象的 API 是否安全?
- 取消API使用的调用
- Lua C API 自定义打印函数,在字符串中传递空格时不调用
- 在 MySQL 连接器C++ API 中使用一个函数调用执行多个查询的正确方法是什么?
- 为什么创建进程 API 调用会导致内存访问冲突?
- 如何使用 Win32 API 从 Excel VBA 中的非"Single-Threaded Apartment"线程调用 InternetGetProxyInfo
- 引发访问冲突的 Win32 API 调用
- 父进程中的挂钩 api 调用
- 如果在 DLL 和调用应用程序中使用 GPGPU API,会发生什么情况
- E/libEGL:调用没有当前上下文的 OpenGL ES API (每个线程记录一次) - Android/SDL
- 如何监视应用程序进行的Windows系统API调用?
- 如何在 go 中调用带有 .lib 和.dll文件的预构建 API
- UNIX API 调用:使用 read() 函数打开文件并将其打印到屏幕上会增加额外的随机字符
- 从C++调用Microsoft视觉 API 时出错
- 使用JNI调用API创建一个java7JVM
- 从 Python 调用 API 时dynamic_cast失败C++