C ++プロジェクトでは、Cソースファイルの.hファイルを含めると、CとC ++の標準が異なるため、多くのエラーが発生します。
C ++プロジェクト(またはmain.cpp)でCソースファイルを使用するにはどうすればよいですか?
4 に答える
最大の信頼性のために:
- CソースをCコンパイラでコンパイルします。
- C++ソースをC++コンパイラでコンパイルする
- できれば、main()関数をC++で記述してください。
- プログラムをC++コンパイラにリンクします。
extern "C" { ... }
Cヘッダー自体がC++を認識していること、またはC++コードにブロック内にCヘッダーが含まれていることを確認してください。
どちらか(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 */
または(C ++ソースコード):
extern "C" {
#include "cheader.h"
}
最新のCスタイルは、CおよびC++言語の一般的なサブセットに非常に近いものです。ただし、任意のCコードは非常に多くの理由でC ++コードではなく、CソースファイルをC ++ソースファイルに呼び出すだけでは(拡張子を変更するか、C ++コンパイラでコンパイルするだけで)成功する保証はありません。 。一般に、CをCとして、C++をC++としてコンパイルし、結果のオブジェクトファイルをC ++コンパイラにリンクする方が簡単です(正しいサポートライブラリが呼び出されるようにするため)。
ただし、MSVCコンパイラがMFCを使用するプログラムはC ++でのみ作成する必要があると言っている場合(MFCではC ++コンパイルが必要です(.cppサフィックスを使用)が報告されたエラーです)、Cコードを確認する以外に選択肢はありません。 C++コードとしてコンパイル可能です。つまり、malloc()
etalからの戻り値をキャストする必要があります。void *
キャストを使用してを他のポインタ型に変換しない他の場所について心配する必要があります。sizeof('a') == 4
Cとsizeof('a') == 1
C++では心配する必要があります。使用する前に、すべての関数が宣言されていることを確認する必要があります。CコードでC++キーワードが使用されていないことを確認する必要があります(特に、typename
場合によっては、完全なリストは非常に大きくなります)。class
inline
一部のサークルでは、柔軟な配列メンバー、指定された初期化子、複合リテラル、可変長配列など、C++2003またはC++2011にはないC99の機能の使用について心配する必要があります。の上。ただし、CコードがMSVC用である場合、それはおそらく問題にはなりません。これらの機能は、MSVC Cコンパイラではサポートされていません(C99ではなくC89のみをサポートしています)。
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>)
(1)
接尾辞は、CPPリファレンスの脚注です。
(1)
— C++11で意味が変更されました
C ++はCソースへの「下位互換性」を説いているので、オプションはCソースを.cppファイルにコピーしてビルドすることです。現在、C ++は完全な下位互換性がないため、Cソースでいくつかの変更が必要になる場合がありますが、通常は最小限のエラーでビルドする必要があります。.cが使用するCライブラリを含めるようにしてください(コンパイラがCもサポートしていることを考慮して)
#include <stdio.h>
#include <string.h>
//so on
一部のプリコンパイル済みライブラリではなくソースコードのみを使用している場合、ほとんどの場合、.cファイルの名前を.cppファイルに変更できます。