我有一个包含以单精度和 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/