包装任何API函数
Wrapping any API Function
我正在包装Windows API,我希望让错误检查变得容易使用,而且很有帮助。目前,我有一个全局错误对象,其函数set
用于处理新错误。set
函数有四个参数:bool Error::set (const int code, const char * file, const char * const function, const int line);
该函数使用文件、函数和行参数将它们显示在格式良好的消息中。
为了简化错误设置,有一个宏#define setError() error.set (GetLastError(), __FILE__, __FUNCTION__, __LINE__);
。通过这种方式,我可以随时使用setError()
来响应API函数设置的错误,方法是在调用API函数后添加它。
不幸的是,这导致代码看起来像这样:
SomeAPIFunction();
setError();
AnotherAPIFunction();
setError();
构造函数也有一个问题:
MyClass:MyClass()
: a (SomeAPIFunction), b (AnotherAPIFunction)
{
setError(); //what if both functions set an error?
}
正如您所看到的,通过使用成员初始值设定项语法,我实际上限制了自己。
解决这个问题的一种方法是包装每个API函数:
int someAPIFunction()
{
int ret = SomeAPIFunction();
setError();
return ret;
}
错误消息的function
部分会告诉我是哪个函数引发了错误。当然,这是最糟糕的处理方式。
解决方案似乎是使用可变模板。问题是,我不知道我应该做什么来让他们为此工作。我想最终的代码看起来像以下代码之一:
wrap<int, SomeAPIFunction (5)>();
wrap<int, SomeAPIFunction, 5>();
wrap<int, SomeAPIFunction> (5);
我读过一些关于开始可变模板的东西,但它们都让我不知道如何设置这样的模板。有人能给我指正确的方向吗?
我在一个类似的问题上发现了以下内容:
#include <iostream>
template<void f(void)>
struct Wrap {
void operator()() const {
std::cout << "Pre call hook" << std::endl;
f();
}
};
namespace {
void test_func() {
std::cout << "Real function" << std::endl;
}
}
const Wrap<&test_func> wrapped_test_func = {};
int main() {
wrapped_test_func();
return 0;
}
答辩人指出,为了使这一点足够通用,有必要使用各种各样的模板。这是一个开始,但我很失落,也很感激在这件事上得到的任何帮助。
我认为您将能够使用以下语法:
wrap(&SomeAPIFunction, arg1, arg2);
关键是让编译器使用类型推导来确定模板类型参数,因为它们在匆忙中会变得非常混乱。
代码应该看起来像:
template<typename TRet, typename... TArgs>
TRet wrap( TRet(WINAPI *api)(TArgs...), TArgs... args )
{
return api(args...);
}
当然,您会希望使用宏来隐藏函数运算符的地址,使用字符串化来存储函数名称,还存储文件名和行号,并将所有这些传递给实际的变元函数。为此,您需要可变宏。事实上,你能只使用可变宏而不使用模板来完成所有这些吗?
- 为 NewObjectA() 函数创建 jvalues 的参数数组时出错 - JNI Invocation API
- 节点插件 API 将数组作为函数参数传递
- 为什么我在 Windows API 中得到对 TextOut() 函数的未定义引用?
- 调用 Win32 API 函数时未定义的引用
- 谁拥有作为指向 Windows API 函数的指针传递的值?
- 使用 Node.js N-API 调用 C 函数时,不会显示预期的输出
- 如何创建面向C++函数的C API
- 将uint8_t*buffer和size_tbufferlen从C++传递到C中的API函数的最佳方式是什么
- 在类中设置 PubSubClient API 的回调函数
- 使用宏替换工厂模式样式 API 中的"create()"函数
- 是否有一个Windows驱动程序函数可以执行Windows文件api SeFileAttributes的等效功能
- Lua C API 自定义打印函数,在字符串中传递空格时不调用
- 在 MySQL 连接器C++ API 中使用一个函数调用执行多个查询的正确方法是什么?
- 如何仅使用 c/python API 将 c++ 成员函数绑定到 python?
- 是否有任何 C 函数或 API 来获取当前登录用户下运行的进程列表
- 包装 C API 通过C++接受迭代器的函数获取原始指针
- 在Xcode(mac api)上,是否有任何带有Sleep()函数/命令的文件?
- 构造函数中发生异常时如何释放 API 使用的资源
- 如何将CString转换为使用WCHAR的Windows API和自定义函数?
- Win32 C API:替代损坏的execl*()系列函数?