c++ - 模板 extern "C"函数以从 C++ 调用具有不同类型的 Fortran 函数

标签 c++ templates fortran extern

我有一个包含以单精度和 double 编译的 Fortran 函数的库,但我无法更改该库的源代码中的任何内容。理想情况下,我会将外部函数定义为

template<typename TF> extern "C" void fortran_function(TF*)

然后调用该函数(两次调用都在同一范围内)

double a[3] = { 2, 3, 4 };
fortran_function<double>(a);

float b[3] = { 2, 3, 4 };
fortran_function<float>(b);

但是,这是不允许的。我该如何优雅地解决这个问题?

最佳答案

此要求存在非常严重的问题。 C++ 确实允许重载 native C++ 函数,但不允许重载“C”语言链接。链接规范 [dcl.link] §6 说:

At most one function with a particular name can have C language linkage.

并且您的模板化尝试等同于显式声明:

extern "C" void fortran_function(double *);
extern "C" void fortran_function(float *);

这将声明 2 个具有 C 语言链接和相同名称的不同函数 => C++ 标准明确禁止。

其背后的基本原理是常见的实现使用名称重整 来构建一个包含参数类型的函数标识符,以便链接器能够识别它们。 C 语言链接精确地避免了名称重整以允许与 C 语言函数接口(interface)。这立即消除了任何过载的可能性。


无论如何,您将无法定义 2 个具有相同名称但使用不同参数的 C 或 Fortran 函数。我能想到的最好的方法是手动处理:

extern "C" void fortran_function_double(double *);
extern "C" void fortran_function_float(float *);

也许你可以使用宏来简化多重声明,但我对宏元编程真的不够熟练......

关于c++ - 模板 extern "C"函数以从 C++ 调用具有不同类型的 Fortran 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50644894/

相关文章:

linux - 使用 gfortran 在 makefile 中进行库链接

c++ - 稳定排序C++ HashMap -保留相等元素的插入顺序

c++ - 使用 Live555 从连接到 H264 编码器的 IP 摄像机流式传输实时视频

c++ - 类型别名和模板模板参数推导

c++ - 从 Foo<Derived> 到 Foo<Base> 的转换

fortran - openmp 长指令列表 fortran77 的语法

c++ - 重新定义 __LINE__ 和 __FILE__ 常量

c++ - int 到字符串的转换

c++ - 为什么这个交换函数调用不明确?

Fortran 用户定义的运算符优先级规则