programing

C++ 프로젝트에서 C 소스 파일을 어떻게 사용합니까?

elecom 2023. 10. 20. 13:26
반응형

C++ 프로젝트에서 C 소스 파일을 어떻게 사용합니까?

C++ 프로젝트에서 C 소스 파일의 .h 파일을 포함하면 C와 C++ 사이의 표준이 다르기 때문에 많은 오류가 발생합니다.
C++ 프로젝트(또는 main.cpp)에서 C 소스 파일을 사용하는 방법?

최대의 신뢰성을 위해:

  • C 컴파일러로 C 소스를 컴파일합니다.
  • C++ 컴파일러로 C++ 소스 컴파일
  • 메인() 함수를 C++로 쓰는 것이 좋습니다.
  • C++ 컴파일러로 프로그램을 연결합니다.

C 헤더가 C++를 인식하고 있거나 C++ 코드에 C 헤더가 포함되어 있는지 확인합니다.extern "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()그 외; 당신은 당신이 a를 변환하기 위해 깁스를 사용하지 않는 다른 장소에 대해 걱정해야 합니다.void *다른 포인터 타입으로; 당신은 걱정해야 합니다.sizeof('a') == 4캔드로sizeof('a') == 1C++에서는 모든 함수가 사용되기 전에 선언되도록 해야 합니다. 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++에서 C를 호출하는 것은 매우 쉽습니다. 각 C 함수에는 가능한 하나의 비각 기호만 있으므로 추가 작업이 필요하지 않습니다.

main.cpp

#include <cassert>

#include "c.h"

int main() {
    assert(f() == 1);
}

c.h

#ifndef C_H
#define C_H

/* This ifdef allows the header to be used from both C and C++. */
#ifdef __cplusplus
extern "C" {
#endif
int f();
#ifdef __cplusplus
}
#endif

#endif

c.c.c

#include "c.h"

int f() { return 1; }

실행:

g++ -c -o main.o -std=c++98 main.cpp
gcc -c -o c.o -std=c89 c.c
g++ -o main.out main.o c.o
./main.out

설명을 드렸습니다.extern "C"C++에서 외부 "C"의 영향은 무엇입니까?

GitHub에서의 예.

C 예제에서 실행 가능한 최소 C++

에서 C++를 호출하는 것은 좀 어렵습니다. 노출하고 싶은 각 함수의 각 버전을 수동으로 만들어야 하기 때문입니다.

여기서는 C++ 함수 과부하를 C에 노출시키는 방법을 설명합니다.

본전의

#include <assert.h>

#include "cpp.h"

int main(void) {
    assert(f_int(1) == 2);
    assert(f_float(1.0) == 3);
    return 0;
}

cpp.h

#ifndef CPP_H
#define CPP_H

#ifdef __cplusplus
// C cannot see these overloaded prototypes, or else it would get confused.
int f(int i);
int f(float i);
extern "C" {
#endif
int f_int(int i);
int f_float(float i);
#ifdef __cplusplus
}
#endif

#endif

cpp.cpp

#include "cpp.h"

int f(int i) {
    return i + 1;
}

int f(float i) {
    return i + 2;
}

int f_int(int i) {
    return f(i);
}

int f_float(float i) {
    return f(i);
}

실행:

gcc -c -o main.o -std=c89 -Wextra main.c
g++ -c -o cpp.o -std=c++98 cpp.cpp
g++ -o main.out main.o cpp.o
./main.out

GitHub에서의 예.

C++는 C 소스에 "역호환성"을 전하므로 C 소스를 .cpp 파일에 복사하여 빌드하는 것이 옵션입니다.이제 C++는 완전한 하위 호환성을 갖지 않으므로 C 소스에서 몇 가지를 변경해야 할 수도 있지만 일반적으로 오류를 최소화하여 구축해야 합니다..cs가 사용하는 C 라이브러리를 포함해야 합니다(C 역시 컴파일러가 지원하는 것을 고려하면).

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

일부 미리 컴파일된 라이브러리가 아닌 소스 코드를 사용하는 경우 대부분의 경우 .c 파일 이름을 .cpp 파일로 변경할 수 있습니다.

언급URL : https://stackoverflow.com/questions/13694605/how-to-use-c-source-files-in-a-c-project

반응형