我有一个与硬件接口的第三方封闭源码c库,该库有一些api函数,它们接受void *
参数来读/写和配置一些io,如下所示:
int iocall(int cmd, void * args);
int iorw(int cmd, void * buff, size_t buff_size);
我想把这些封装在一个c++类中,以便能够注入该类,能够使用gtest模拟它,引入异常,并在上层服务类中消除所有返回值检查。到目前为止一切顺利。下面是我的问题:当涉及到void *
参数时,为该类设计接口的最佳方法是什么?
interface.h
class wrap:
{
virtual void wrap_iocall(int cmd, ??) = 0;
}
interface_impl.h
class wrap:
{
void wrap_iocall(int cmd, ??) override
{
int ret{iocall(cmd, ??)};
// do some more stuff, e.g. exceptions and so on
}
}
我的第一步是用专用类型重载调用-但由于有很多专用类型,这可能是一个维护的痛苦,当需要另一个调用时(例如,其他硬件调用),我将需要更改接口+库可能会得到更新,这迫使我更新类型。
我考虑的第二件事是使用std::any
,这将适合我的用例,但我不确定如何将指向std::any
容器的指针传递给底层c函数?我考虑将其推入std::vector<std::any>
,并使用.data()
函数传递指针。但是,然后我就只剩下一个猜测的大小,我认为容器?这听起来像一个非常糟糕的尝试,以实现我正在寻找的。
我遇到的第三件事是一个使用模板的解决方案,但如果我的理解是正确的,这些东西不可能是虚拟的,因此打破了我的意图,模拟界面,要求它是虚拟的。所以我认为这可能也行不通。
目前我能想到的最后一件事是在 Package 函数中坚持只使用void *
,并让上层服务层处理类型转换,例如为特定的设备调用分配struct,并将指针传递到 Package 器的void *
参数。这是目前为止我最不喜欢的选项。
我想坚持类型安全函数参数的原则,但我不确定如何从这里继续下去。任何帮助/反馈都是非常感谢的!
1条答案
按热度按时间64jmpszr1#
我不确定我是否正确地理解了你的需求。然而,似乎你自己也不确定你需要什么:)
因此,我提出了一个基于模板和参数包的解决方案,希望这个例子能让你了解可以做些什么。
https://godbolt.org/z/eqbz8s6oe