【问题标题】:Calling a template function from a C file从 C 文件调用模板函数
【发布时间】:2017-04-02 09:09:31
【问题描述】:

我知道模板不是用 C 定义的。但是在我的例子中,我有一个用 C++ 编写的 API,它被一个用 C 编写的应用程序使用。我希望在 API 中添加一个模板函数。该函数在abc.cpp中定义如下:

template<typename T> T function_name(T param1){
  ...
  ...
  return val;
}

abc.hpp中的声明如下:

template<typename T> T function_name(T);

这个函数是从 xyz.c 调用的:

int a ,b = 5;
a = function_name(b);

但是,它在 abc.cpp 和 abc.hpp 中都显示以下错误:

 error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘<’ token
 template<typename T>

即使使用 extern "C" 也无济于事(导致错误:带有 C 链接的模板)。我的疑问是,是否可以以这种方式调用此模板函数?如果是,如何实现?谢谢你。

【问题讨论】:

  • “错误:带有 C 链接的模板”错误是您应该采取的提示;不打算用 C 直接调用 C++ 来完成。您必须知道模板函数的实例化的损坏的 C++ 名称,然后 C 代码会调用它。这会将您与特定的 C++ 编译器联系起来(甚至可能是特定版本的编译器)。正确的做法是extern "C" int template_int_function_name(int param1) { return function_name(param1); },然后C调用template_int_function_name()。这为您提供了模板函数的 C 可调用包装器。
  • 应用程序可能突然变成用 C++ 编写的 ;-)(如果您决定使用 C++ 编译器编译它)。您可能需要进行一些小的调整,特别是如果代码遵循 unwind 的建议不要强制转换 malloc() 的返回值,但编辑通常相当小。
  • @JonathanLeffler Re "call template function directly through mangled name": 如果没有 C++ 代码,即这里没有库内的代码,则实例化甚至可能不存在(并导致链接时错误),使用 int 参数调用函数。如果函数是最近添加到库中的,很有可能。
  • @PeterA.Schneider:是的;这是尝试调用损坏名称的另一个可能缺陷。不太可能,但可能。这只是一个彻底死去的想法的棺材上的另一个钉子——这绝对不是正确的方法。
  • 是的,C 代码需要使用的每种类型都需要包装器。不使用 C 中的模板函数是明智的。用 C++ 重写这些函数可能会更好,但惯用的现代 C++ 与 C 非常不同。

标签: c++ c templates template-function


【解决方案1】:

由于 C 不支持模板,您可以考虑使用 Type-Generic Functions - 一种定义泛型表达式的基于宏的方法。

如果不是这种情况,我建议继续使用 C++ 编译器。

【讨论】:

  • 如果你的意思是_Generic,它不是基于宏的解决方案,而是语言中的完整运算符——它在标准§6.5.1.1 节中描述通用选择,它是第 6.5.1 节 主要表达式 的一部分。 6.10 节描述了预处理器。
【解决方案2】:

由于您已经混合了 C 和 C++(因此必须注意可能出现的问题),另一个解决方案是继续使用 C++ 开发应用程序。这样,新代码可以使用 C++ 库的所有优秀功能,例如模板 ;-)、重载函数等,并且可以访问 C++ 的标准库,从而大大提高生产力。

我没有看到在应用程序中使用 C++ 处理新源文件的主要障碍;在编辑时将现有的 C 文件切换到 C++ 是否容易和值得是另一个问题。

【讨论】:

    【解决方案3】:

    不,当然不,C 中不存在模板函数,您无法使用 C 编译器解析模板声明。

    您将不得不在 C++ 端为模板的 int 实例添加一个 C 包装器,然后调用它(例如 function_int() 之类的东西)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-09
      • 2015-09-22
      • 2021-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多