【问题标题】:Why can't I include C files in main.cpp?为什么我不能在 main.cpp 中包含 C 文件?
【发布时间】:2017-06-01 14:24:59
【问题描述】:

我只有用 C 语言编写的代码。主函数为main.c,包含#include "Flash.h"等其他c文件。

我想保持项目正常运行,但能够添加 cpp 文件。 有人告诉我,我必须将 main 更改为

main.cpp

这将在编译时产生 250 个错误-关于包含的 c 文件

将主文件转换为 cpp 并仍然包含 C 文件的正确方法是什么?

main.cpp:

#include "Flash.h"
int main(void)
{
....
}

我已经阅读了How to use C source files in a C++ project?,它并没有为我提供直接解决问题的方法(我的编译器无论如何都会使用 c++)。

编辑

在有人问我会杀了我之前(不知道你为什么这么咄咄逼人),我只收到 3 种错误 250 次:

'->' cannot appear in a constant-expression
'&' cannot appear in a constant-expression
a cast to a type other than an integral or enumeration type cannot appear in a constant-expression

编辑 2: 以下是一些行(使用 SDK 运行某些 RF 芯片): 大部分错误来自此部分

typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
{
    NRF_GPIOTE_TASKS_OUT_0     = offsetof(NRF_GPIOTE_Type, TASKS_OUT[0]), /**< Out task 0.*/
    NRF_GPIOTE_TASKS_OUT_1     = offsetof(NRF_GPIOTE_Type, TASKS_OUT[1]), /**< Out task 1.*/
    NRF_GPIOTE_TASKS_OUT_2     = offsetof(NRF_GPIOTE_Type, TASKS_OUT[2]), /**< Out task 2.*/
    NRF_GPIOTE_TASKS_OUT_3     = offsetof(NRF_GPIOTE_Type, TASKS_OUT[3]), /**< Out task 3.*/
#if (GPIOTE_CH_NUM > 4) || defined(__SDK_DOXYGEN__)
    NRF_GPIOTE_TASKS_OUT_4     = offsetof(NRF_GPIOTE_Type, TASKS_OUT[4]), /**< Out task 4.*/
    NRF_GPIOTE_TASKS_OUT_5     = offsetof(NRF_GPIOTE_Type, TASKS_OUT[5]), /**< Out task 5.*/
    NRF_GPIOTE_TASKS_OUT_6     = offsetof(NRF_GPIOTE_Type, TASKS_OUT[6]), /**< Out task 6.*/
    NRF_GPIOTE_TASKS_OUT_7     = offsetof(NRF_GPIOTE_Type, TASKS_OUT[7]), /**< Out task 7.*/

在这些行上重复相同的错误:

a cast to a type other than an integral or enumeration type cannot appear in a constant-expression

【问题讨论】:

  • C 和 C++ 仍然是两种截然不同的语言,你不能指望为 C 编译器编写的头文件可以完美地与 C++ 编译器一起编译。
  • 为什么要混合 C 和 C++?难怪它不编译。您必须改用main.c
  • @Curnelious 这并不一定很糟糕,但你必须小心编译。仔细阅读您添加到帖子中的链接。您应该将 C 代码编译为 C,将 C++ 代码编译为 C++,然后适当地链接它们。
  • 如果您的Flash.h 是公开的,请至少提供一些链接。否则,给出一些错误消息并将它们周围的几行Flash.h 复制并粘贴到您的问题中。我们无法猜测您的错误消息。
  • @Curnelious 你真的不需要消极对待这些东西。人们在告诉你如何改进你的问题,以便得到解答。您应该在问题中添加的这些内容非常重要。你在做正确的事,包括他们。

标签: c++ c


【解决方案1】:

C++ 中的#include 指令是对源代码的字面包含。想象一下 main.c 包含的 Flash.h 中的 C 源代码做一些与 C++ 不兼容的事情,比如

typedef int class;

现在,在您的 main.cpp 中,您有

#include "Flash.h"

就好像您在 C++ 源文件中直接有此代码 typedef int class; - 所以这是一个错误。


如果你有带有 C 头文件的 C 源代码,你根本不需要使用 C++!

如果您想编写新的 C++ 代码并使其调用旧代码(反之亦然),只需使用链接器即可。让 C++ 代码包含 C++ 标头,单独,C 代码包含 C 标头,链接器会将您的所有代码组合成一个可执行文件。


要使您的 C 和 C++ 部分协同工作,您需要一个额外的头文件。例如称它为c-cpp-interface.h。然后将其包含在所有 C 和 C++ 源文件中:

#include "c-cpp-interface.h" // in C files

extern "C" {
    #include "c-cpp-interface.h" // in C++ files
}

此文件应使用通用 C/C++ 子集语言编写。也就是说,主要是 C 语言,但具有更高的类型安全性(例如,所有函数的原型必须完全编写,没有隐含的 ... 参数)。

理想情况下,您现有的 C 头文件可以这样使用。但是,C 头文件经常会堆积如山,创建一个新文件可能比清理现有文件更实用。


查看您收到的实际错误消息(使用offsetof),您应该尝试在 C - C++ 接口中使用尽可能少的代码。不要把实现细节(比如各种常量的值)放在那里。只有其他语言调用的函数的声明/原型(C 调用 C++,反之亦然)。

【讨论】:

  • 如何“分开”?我有一个项目,你能详细说明如何“单独”做到这一点吗?最后我有 1 个主文件,这个主文件应该使用 C 和 C++,那么你会怎么做呢?
  • 您的项目应该有 2 个源文件,main.canother.cpp。我从未使用过您的 C/C++ 系统,但“项目”的概念似乎对所有系统都很常见 - 项目是源文件的集合。
  • 所以你有 x.c 和 y.cpp ,你有 1 个主文件。你想在 main 中同时使用 x 和 y,你会怎么做?在某些时候,它们将不得不相交,因为它是同一个项目,此时您必须将 C 包含到 C++ 或相反的 .
  • 你有一个带有 c 端函数定义的头文件,它位于 c++ 头文件中,因此链接器可以告诉 c++ 代码哪个 c 函数可用。该标头可以是常见的,只要它不包含任何破坏 either c 或 cpp 的内容,请参阅此 stackoverflow.com/questions/3789340/…
【解决方案2】:

您发布的问题指出您需要包装 inclues

extern "C" {
#include "cheader.h"
}

在你的情况下,

extern "C" {
#include "Flash.h"
}
int main(void)
{
}

并且在每个想要使用 C 代码的 cpp 中,使用 extern "C" 围绕包含。

【讨论】:

  • ... 但Flash.h 必须仍然是有效的 C++。如果不是,除了“修复”标题之外,别无他法。 extern "C" 只是关闭/调整名称修改;而已。它不会进入某种“C 语言模式”。最终,除非 Flash.h 被设计为同时用于 C 和 C++,否则你不能这样做。它们是两种截然不同的语言。
  • @Curnelious:如果没有minimal reproducible example 形式的具体示例,就无法判断。 Flash.h 是从哪里来的?谁写的?你可以问他们这个吗?但是,是的,一般来说,如果你有一个 C 程序,除非你(或朋友)将程序翻译成你想使用的另一种编程语言,否则你“永远被 C 困住”。
  • @Cumelious:请编辑您自己的问题,不要在这里发表评论。正如我所说,在确切的错误周围至少给出几行flash.h,并给出确切的错误消息。如果可以(并且被允许),请在某处发布您的源代码。
  • @Curnelious 请编辑您的问题并在此处添加此有价值的信息。您的问题上有一个edit 链接。
  • @Curnelious:请不要发表评论,但编辑您的问题通过提供更多信息来改进它(很多)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-09-09
  • 1970-01-01
  • 1970-01-01
  • 2018-05-30
  • 1970-01-01
  • 2010-11-01
  • 1970-01-01
相关资源
最近更新 更多