【发布时间】: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