【问题标题】:Clang C Compiler 'class' keyword reserved?Clang C编译器'class'关键字保留?
【发布时间】:2012-09-14 00:59:30
【问题描述】:

您好,我正在使用 xcode 编译 ffmpeg,我相信它使用 clang 进行编译。在 ffmpeg 中有一个带有名为“class”的成员变量的结构,我相信这在 C 中非常好,但 clang 正试图将其解析为关键字。知道如何解决吗?基本上cpp文件中的以下内容会导致错误:

extern C {
    typedef struct {
        int class;
    } SomeStruct;
}

它试图将类解释为关键字。

仅供参考,在 ffmpeg 中引发错误的文件是 libavcodec/mpegvideo.h,我需要包含它才能访问 MpegEncContext 结构以提取运动图信息。

编辑

上面的代码示例只是为了演示错误。但也许它可以通过另一种方式修复。在我的实际代码中,我有这样的:

#ifdef __cplusplus
extern "C" {
#endif

    #include "libavcodec/mpegvideo.h"
    #include "libavformat/avformat.h"

#if __cplusplus
} //Extern C
#endif

如何将这两个文件包含为 C 文件而不是 C++?

谢谢

【问题讨论】:

  • 而您的 Xcode- (ffmpeg) 相关问题是:
  • 呵呵:extern COBOL { ADD A TO B GIVING C }
  • 我的 xcode ffmpeg 相关问题是,如何将该标头包含到 c++ 文件中并在 Xcode 中编译?
  • 没有办法在 C++ 中使用这样的声明。您需要按摩源(在任何地方重命名该成员)或在 C 中编写一个具有与 C++ 不冲突的可见界面的包装器。您可能会也可能无法使用宏玩一些技巧(我不熟悉这些来源,所以我不确定宏技巧是否容易实现)。

标签: c xcode ffmpeg clang


【解决方案1】:

如果您无法选择重命名这些头文件中的任何内容,则可以将 class 标记替换为其他内容

#ifdef __cplusplus
extern "C" {
# define class videoClass
#endif

    #include "libavcodec/mpegvideo.h"
    #include "libavformat/avformat.h"

#if __cplusplus
# undef class
} //Extern C
#endif

这是一个相当肮脏的 hack,但是对于这样糟糕的接口代码,您没有太多选择。真正的解决方案是让这些文件中的所有struct 成员使用我们使用某种前缀左右的名称,就像在网络层代码中所做的那样。所有成员都有一些前缀ss_sa_,这样的问题不太可能发生。

【讨论】:

  • 这是我在回答中写下关于肮脏技巧时想到的主要肮脏技巧:) (别担心,我不会投反对票,因为您确实遇到了麻烦指出并解释问题,并明确表示它是肮脏的)
【解决方案2】:

在 C 中完全没问题。当您将其构建为 C++ 时,您会遇到错误,因为 class 是 C++ 关键字。

就修复它而言,您通常会选择class 以外的标识符。但是,ffmpeg 开发人员可能不太同意这种变化。因此,您可能需要:

  • 将该标头的可见性限制为 C 翻译
  • 或编辑您自己的副本以便在 C++ 翻译中使用它

幸运的是,在这种情况下,您还使用了对 C99 特性有良好支持的 C 编译器。不能很好地支持 C99 的 C 编译器对于 ffmpeg 源代码特别麻烦(因为您随后会将整个程序编译为 C++ 以获得 C99 功能,并且冲突计数会高得多)。

(您可以使用其他肮脏的技巧来尝试解决问题,但我不会提及它们)

【讨论】:

  • 你能解释一下我如何将这些标题的可见性限制为 C 翻译吗?我想我可以将使用该文件的任何代码移动到 .c 文件中。但我仍然需要在某些时候从 c++ 文件中包含该 .c 文件。
  • 我想我可以将类变量重命名为其他任何东西,因为它只使用头文件作为参考(ffmpeg 已经编译到库中)但我只是不喜欢弄乱源文件如果我不需要,更新有点困难。
  • @user1689196 确定。你在正确的轨道上;您需要创建一个薄包装层(在 C 中),然后您可以从 C++ 调用它以与 SomeStruct 交互,或者只处理程序的那个方面,其中包括 SomeStruct 专门用于更大的 C 实现。跨度>
  • @user1689196 是的,它肯定会使更新、构建和维护变得复杂,但是......你只需要选择你认为较小的邪恶(除非有人提出更好的解决方案) .第一种选择更安全,但需要更多的前期工作。第二个随着时间的推移需要更多的维护,并且通常更容易引入错误。当然,您可能只想对每个稳定版本进行干净的检查,然后对其进行编辑(每隔几个月丢弃一次更改)。这不好玩:)
【解决方案3】:

基本上cpp文件中的以下内容会导致错误

.cpp 文件作为 C++ 文件处理,而不是 C,class 是 C++ 中的保留字。

【讨论】:

  • 但是 extern C 不应该强制它使用 C 编译器吗?
  • @user1689196,绝对不是。这只会改变符号的链接以停止名称修改。您可以使用 -x 标志强制使用语言。
  • 不,extern C 只是改变了名称修改的工作方式。要编译为 C,请使用 .c
  • 嗯,那你通常是怎么做的。实际上,我只是包含 ffmpeg 头文件,而不是实际声明内联结构。它仍然给我错误。
  • @user1689196:您编写 C 函数来为您处理 FFmpeg 代码,然后在 C++ 中声明和调用这些函数,而无需在 C++ 源代码中包含实际的 FFmpeg 标头。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-08
  • 2011-02-02
相关资源
最近更新 更多