如何在 C++ 项目中使用 C 源文件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13694605/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 17:38:46  来源:igfitidea点击:

How to use C source files in a C++ project?

c++c

提问by Al2O3

In a C++ project, including .h files of C source files will cause many errors because of different standards between C and C++.
How to use C source files in a C++ project (or in main.cpp)?

在C++项目中,包含C源文件的.h文件会因为C和C++的标准不同而导致很多错误。
如何在 C++ 项目(或 main.cpp)中使用 C 源文件?

回答by Jonathan Leffler

For the maximum reliability:

为了获得最大的可靠性:

  • Compile the C source with a C compiler.
  • Compile the C++ source with a C++ compiler
  • Preferably, write the main() function in C++.
  • Link the program with a C++ compiler.
  • 使用 C 编译器编译 C 源代码。
  • 使用 C++ 编译器编译 C++ 源代码
  • 最好用 C++ 编写 main() 函数。
  • 将程序与 C++ 编译器链接。

Make sure that the C headers are either themselves aware of C++ or that the C++ code includes the C headers inside an extern "C" { ... }block.

确保 C 头文件本身知道 C++,或者 C++ 代码在extern "C" { ... }块内包含 C 头文件。

Either (C header file cheader.h):

任一(C 头文件cheader.h):

#ifndef CHEADER_H_INCLUDED
#define CHEADER_H_INCLUDED

#ifdef __cplusplus
extern "C" {
#endif

...main contents of header...

#ifdef __cplusplus
}
#endif

#endif /* CHEADER_H_INCLUDED */ 

or (C++ source code):

或(C++ 源代码):

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

Modern C style is very close to the common subset of the C and C++ languages. However, arbitrary C code is not C++ code for any of a very large number of reasons, and simply calling the C source files C++ source files (by changing the extension, or simply by compiling with the C++ compiler) is not guaranteed to be successful. In general, it is easier to compile C as C and C++ as C++ and then link the resulting object files with the C++ compiler (to ensure the correct support libraries are invoked).

现代 C 风格非常接近 C 和 C++ 语言的公共子集。但是,任意 C 代码由于多种原因都不是 C++ 代码,并且仅调用 C 源文件 C++ 源文件(通过更改扩展名,或仅通过使用 C++ 编译器进行编译)并不能保证成功. 通常,将 C 编译为 C,将 C++ 编译为 C++,然后将生成的目标文件与 C++ 编译器链接(以确保调用正确的支持库)更容易。

However, if the MSVC compiler is saying that programs using MFC have to be written solely in C++ (MFC requires C++ compilation (use a .cpp suffix)is the reported error), then you may have no choice but to ensure that your C code is compilable as C++ code. That means you'll have to cast the return values from malloc()et al; you have to worry about other places where you do not use a cast to convert a void *into some other pointer type; you have to worry about sizeof('a') == 4in C and sizeof('a') == 1in C++; you have to ensure that every function is declared before it is used; you have to ensure your C code does not use any C++ keywords (typename, classin particular; also inlinesometimes — but the complete list is quite large).

但是,如果 MSVC 编译器说使用 MFC 的程序必须仅用 C++ 编写(MFC 需要 C++ 编译(使用 .cpp 后缀)是报告的错误),那么您可能别无选择,只能确保您的 C 代码可编译为 C++ 代码。这意味着您必须转换来自malloc()et al的返回值;您必须担心其他不使用强制转换将 a 转换void *为其他指针类型的地方;你必须sizeof('a') == 4在 C 和sizeof('a') == 1C++ 中担心;您必须确保每个函数在使用之前都已声明;你必须确保你的C代码,不使用任何C ++的关键字(typenameclass尤其;也inline有时候-但完整列表是相当大的)。

In some circles, you'd have to worry about the use of features in C99 that are not in C++2003 or C++2011, such as flexible array members, designated initializers, compound literals, variable-length arrays, and so on. However, if the C code is for MSVC, then that probably isn't going to be a problem; those features are not supported by the MSVC C compiler (it only supports C89, not C99).

在某些圈子中,您不得不担心 C99 中 C++2003 或 C++2011 中没有的特性的使用,例如灵活的数组成员、指定的初始值设定项、复合字面量、变长数组等等在。但是,如果 C 代码用于 MSVC,那么这可能不会成为问题;MSVC C 编译器不支持这些功能(它只支持 C89,不支持 C99)。

FWIW: I have a script to hunt down C++ keywords. It contains the following comment:

FWIW:我有一个脚本来寻找 C++ 关键字。它包含以下评论:

# http://en.cppreference.com/w/cpp/keywords
# plus JL annotations
# and                               C (<iso646.h>)
# and_eq                            C (<iso646.h>)
# alignas (C++11 feature)
# alignof (C++11 feature)
# asm                               C (core)
# auto(1)                           C (core)
# bitand                            C (<iso646.h>)
# bitor                             C (<iso646.h>)
# bool                              C99 (<stdbool.h>)
# break                             C (core)
# case                              C (core)
# catch
# char                              C (core)
# char16_t (C++11 feature)
# char32_t (C++11 feature)
# class
# compl                             C (<iso646.h>)
# const                             C (core)
# constexpr (C++11 feature)
# const_cast
# continue                          C (core)
# decltype (C++11 feature)
# default(1)                        C (core)
# delete(1)
# double                            C (core)
# dynamic_cast
# else                              C (core)
# enum                              C (core)
# explicit
# export
# extern                            C (core)
# false                             C99 (<stdbool.h>)
# float                             C (core)
# for                               C (core)
# friend
# goto                              C (core)
# if                                C (core)
# inline                            C (core)
# int                               C (core)
# long                              C (core)
# mutable
# namespace
# new
# noexcept (C++11 feature)
# not                               C (<iso646.h>)
# not_eq                            C (<iso646.h>)
# nullptr (C++11 feature)
# operator
# or                                C (<iso646.h>)
# or_eq                             C (<iso646.h>)
# private
# protected
# public
# register                          C (core)
# reinterpret_cast
# return                            C (core)
# short                             C (core)
# signed                            C (core)
# sizeof                            C (core)
# static                            C (core)
# static_assert (C++11 feature)
# static_cast
# struct                            C (core)
# switch                            C (core)
# template
# this
# thread_local (C++11 feature)
# throw
# true                              C99 (<stdbool.h>)
# try
# typedef                           C (core)
# typeid
# typename
# union                             C (core)
# unsigned                          C (core)
# using(1)
# virtual
# void                              C (core)
# volatile                          C (core)
# wchar_t                           C (core)
# while                             C (core)
# xor                               C (<iso646.h>)
# xor_eq                            C (<iso646.h>)

The (1)suffixes is a footnote at CPP Reference:

(1)后缀是CPP参考脚注:

  • (1)— meaning changed in C++11
  • (1)— 含义在 C++11 中发生了变化

回答by Syntactic Fructose

C++ preaches "backwards compatibility" to C source, so an option would be to copy the C source onto a .cpp file and build. Now C++ is not COMPLETELYbackwards compatible, so you might need to change some things around in the C source, but generally it should build with minimal errors. Just make sure you include the C library's that the .c uses(considering your compiler supports C also)

C++ 宣扬对 C 源代码的“向后兼容性”,因此一个选项是将 C 源代码复制到 .cpp 文件并构建。现在 C++不完全向后兼容,因此您可能需要更改 C 源代码中的一些内容,但通常它应该以最小的错误构建。只需确保包含 .c 使用的 C 库(考虑到您的编译器也支持 C)

#include <stdio.h>
#include <string.h>
//so on

回答by Salchi13

if you are just using the source code and not some precompiled libraries, in most of the cases you could just rename the .c file to a .cpp file

如果您只是使用源代码而不是一些预编译库,在大多数情况下,您只需将 .c 文件重命名为 .cpp 文件