【问题标题】:Compiling extern "c" code with array parameters in gcc在 gcc 中使用数组参数编译 extern "c" 代码
【发布时间】:2017-10-19 08:23:27
【问题描述】:

我正在尝试在 C++ 程序中包含一些 C 函数。 我在包含数组作为参数的函数声明中遇到了一些问题。

extern "C" {
    double Test( int nVar1, double f[nVar1] ) {
        return f[nVar1-1];
    }
}

int main() {
    cout << "!!!Hello World!!!" << endl; 
    double f[2] = {1.0,2.0};
    Test(2, f);
    return 0;
 }

我收到以下错误

  • 'f' 未在此范围内声明
  • 'nVar1' 未在此范围内声明
  • 在 ']' 标记之前在函数体外部使用参数

我使用 Atollic 8.0(GCC 和 C -std=gnu11)

欢迎任何帮助

谢谢你

【问题讨论】:

  • 虽然它是有效的 C99 函数,但它不是有效的 C++(您正在编译的内容)。
  • 只是出于我个人的好奇,你为什么要这样做?为什么不使用 c++ 容器?
  • 我想对遗留的嵌入式 C 代码进行单元测试。我在控制台中使用带有输出的 CppUnit 测试。我面临这样的原型: int ComputedF(int nPoints, int nFunc, double x[], double f[nPoints][nFunc], double df[nPoints][nFunc])

标签: c++ c gcc


【解决方案1】:

extern "C" 不适用于在 cpp 源代码中编译 c。只能在 cpp 源代码/头文件中使用 C 的 ABI:修改、调用约定、异常处理......(感谢 Ajay Brahmakshatriya)

通过重整,我想说编译器/链接器使用的函数的内部唯一名称。 C mangling 与 c++ mangling 完全不同,因此不兼容。要在 c++ 中查找 C 函数,您必须告诉编译器/链接器该函数在哪个内部唯一名称下是已知的。

extern "C" 只切换必须使用的 ABI,包括用于创建内部唯一名称以及如何调用函数的 mangling,而不是切换编译模式。

如果你真的想编译c代码,你必须把你的代码放在一个c源文件中,然后单独编译。并使用extern "C"在cpp环境中声明函数,以允许c++代码使用它。 BUT 函数声明必须与 c++ 兼容,而 double Test( int nVar1, double f[nVar1] ) 则不兼容。

function.c,用gcc -c编译:

double Test( int nVar1, double f[] ) {
    return f[nVar1-1];
}

function.h,兼容c和c++:

#ifndef _FUNCTION_H
#define _FUNCTION_H

#ifdef __cplusplus
extern "C" {
#endif

double Test( int nVar1, double f[] );

#ifdef __cplusplus
}
#endif

#endif

main.cpp,用g++ -c编译:

#include "function.h"

int main() {
    cout << "!!!Hello World!!!" << endl; 
    double f[2] = {1.0,2.0};
    Test(2, f);
    return 0;
 }

最后,使用 g++ 链接器链接所有内容:

g++ function.o main.o -o my_program

参见此处的示例:

【讨论】:

  • C stlye 完成的不仅仅是修饰,还有调用约定、异常处理。在这种情况下,ABI 将是正确的术语。
  • C mangling 与 c++ mangling 完全不同 我会说“真正不同”是一种轻描淡写的说法。 C 中根本没有真正的 C++ 风格的名称修饰,因为没有重载。可能有一些基于 ABI 的名称更改,其中符号与源代码中的函数名称不同,但这不是我在处理 C++ 名称修改时所想到的。
  • 但函数声明必须与 c++ 兼容明确谢谢
【解决方案2】:

问题在于数组大小。它不能是可变的,应该是常量。如果您需要传递一个可变大小的数组,那么只需将指针传递给它的第一个元素: double Test( int nVar1, double * f) {

【讨论】:

  • 这种类型的声明从 C99 link 开始工作我想使用现有代码而不更改它
  • 那里看不到像function(int array[count], int count) 这样的东西,只有function(int array[], int count) 不一样
  • link 从 C99 开始,C 语言支持通过简单地指定可变维度来传递可变大小的数组
【解决方案3】:

你有什么建议用 g++ 编译这样的 C 函数,而不必重写这个遗留函数中包含的完整代码

#ifdef __cplusplus
extern "C" {
#endif

int ComputedF(int nPoints, int nFunc, double x[], double f[nPoints][nFunc], double df[nPoints][nFunc])

#ifdef __cplusplus
}
#endif

谢谢

【讨论】:

    猜你喜欢
    • 2014-09-09
    • 1970-01-01
    • 1970-01-01
    • 2021-05-24
    • 2012-05-15
    • 2013-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多