【问题标题】:Function pointers at runtime运行时的函数指针
【发布时间】:2021-10-07 06:20:43
【问题描述】:

背景

我正在开发一个独立于平台(Linux、macOS 和 Windows)的科学成像应用程序,它实现了各种专业相机,每个相机都有制造商提供的 SDK。我目前正在实施一系列新相机,这些相机由一家公司制造,但由具有单独 SDK 的其他制造商品牌。

除了 SDK 函数名称的细微差别外,公共接口是相同的。也就是说,一切都是一样的(函数返回类型和签名等)。唯一的区别是函数名的开头。

SDK 的公共接口示例

int company_1_count_cameras();
bool company_1_init_camera(...);
bool company_1_connect_camera(...);

还有:

int company_2_count_cameras();
bool company_2_init_camera(...);
bool company_2_connect_camera(...);

我希望能够为所有 OEM 相机使用一种实现,但要考虑功能名称的差异。我已经尝试在预处理器定义中使用函数指针,这部分有效。到目前为止,我做了以下工作:

我已将以下内容放入包含文件中:

#define FP( func ) company_2 ## func

在实现中,我已经做到了:

int count = FP(count());

但是,我不确定如何执行此操作,以便编译我的项目以支持所有不同的相机。任何人都可以就实现这一目标的最佳方式提出任何建议吗?

非常感谢 阿曼达

【问题讨论】:

  • 首先选择一种语言。 C 和 C++ 是不同的语言,会有不同的解决方案。第二,你应该学习OOP,接口和接口实现,这就是你申请的任务。

标签: c++ c linux windows macos


【解决方案1】:

更正式的C++方式是定义一个接口定义类:

struct company_interface {
   int (*count_cameras)();
   bool (*init_camera)(...);
   bool (*connect_camera)(...);
};

然后为每个公司实例化一个单独的实例:

const company_interface company_1{
   &company_1_count_cameras,
   &company_1_init_camera,
   &company_1_connect_camera
};

const company_interface company_2{
   &company_2_count_cameras,
   &company_2_init_camera,
   &company_2_connect_camera
};

此时有许多不同的可能设计决策,从传递const company_interface & 到需要对相机做某事的地方,或者使company_interface 本身成为一个实现高级功能的大类。

这种方法的优点是,仅在定义接口定义类实例的翻译单元中才需要实际的相机特定 API。其他都只需要接口类的声明,它会直接通过函数指针调用相机API,不需要在每个需要调用的翻译单元中包含每个相机API的声明。

另外,现在模拟一个模拟相机 API 的单元测试框架是微不足道的。

【讨论】:

  • 您的回答很有道理,我已经能够编写一个小测试程序来证明它有效。但是,我说函数签名是相同的有点太快了。实际上存在一些差异。例如,API 中的一些函数需要不同类型的相机识别句柄。是否可以调整此解决方案使用不同的签名或是否需要其他方法?
  • 是的,许多不同的方法都是可能的,但没有一种万能的、千篇一律的解决方案来解决所有可能的情况。这一切都取决于具体的细节。
【解决方案2】:

您可以使您的 FP 宏依赖于平台特定的宏,如下所示:

#if defined _WIN32
# define FP(...) win32_##__VA_ARGS__
#elif defined __linux__
# define FP(...) linux_##__VA_ARGS__
#elif defined __APPLE__
# define FP(...) apple_##__VA_ARGS__
#else
 static_assert(false, "Unsupported configuration");
#endif

查看更多特定于平台的宏here

请注意,这与函数指针无关。

【讨论】:

  • 函数名称差异不是特定于平台的,所以这不能满足我的需要。
  • @Amanda 您可以为每个公司预定义一个宏,例如 -DCOMP=company1 等,并执行与我展示的类似的操作。
猜你喜欢
  • 1970-01-01
  • 2014-04-26
  • 1970-01-01
  • 2014-05-02
  • 1970-01-01
  • 2016-02-26
  • 2020-06-09
  • 2018-05-22
  • 1970-01-01
相关资源
最近更新 更多