C++ .h만 인클루드했는데 왜 .cpp도 링크에 포함되나요?
웹개발자인데요. 일본소셜게임회사에 전직하게되었습니다.
집에서 독학으로 Cocos2d-x를 공부하는데요
도무지 혼자서 해결이 안돼서 질문해봅니다.
통합환경툴이 자동으로 링크? 인클루드? 해준다는데 이해가 잘 안가네요?
cocos2d-x예제는 sample에 있는데 hellocpp예제의 일부입니다.
// AppDeligate.cpp
#include "HelloWorldScene.h"
bool AppDelegate::applicationDidFinishLaunching() {
Scene *scene = HelloWorld::scene();
}
// HelloWorldScene.cpp
#include "HelloWorldScene.h"
#include "AppMacros.h"
USING_NS_CC;
Scene* HelloWorld::scene()
{
// 'scene' is an autorelease object
Scene *scene = Scene::create();
// 'layer' is an autorelease object
HelloWorld *layer = HelloWorld::create();
// add layer as a child to scene
scene->addChild(layer);
// return the scene
return scene;
}
// HelloWorldScene.h
#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__
#include "cocos2d.h"
class HelloWorld : public cocos2d::Layer
{
public:
// Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
virtual bool init();
// there's no 'id' in cpp, so we recommend returning the class instance pointer
static cocos2d::Scene* scene();
// a selector callback
void menuCloseCallback(Object* sender);
// implement the "static node()" method manually
CREATE_FUNC(HelloWorld);
};
#endif // __HELLOWORLD_SCENE_H__
어째서 AppDeligate.cpp에서 "Scene *scene = HelloWorld::scene();"를 할수 있는거지요?
단지 "HelloWorldScene.h"만 인클루드 했을뿐인데 HelloWorldScene.cpp에 있는 정의 부분을 알고 있다는게 이상하네요??
참고로 이클립스 쓰고 있고요. HelloWorld::scene(); 에서 F3누르면 HelloWorldScene.cpp로 점프합니다.
.h 파일에 넘겨지는 인수와 리턴 값이 명시되어 있기
.h 파일에 넘겨지는 인수와 리턴 타입이 명시되어 있기 때문에, 이 정보만 가지고 함수 호출 코드를 포함하는 오브젝트 파일들을 구성할 수 있습니다.
이 오브젝트 파일들을 모아서 실행파일을 만드는 링크 과정에서 실제 함수의 주소가 포함되게 되죠.
C++ 컴파일과 링크
컴파일은 cpp 파일 단위로 합니다. 그러면 AppDeligate.cpp를 컴파일한 AppDeligate.o 파일이 생성되고, HelloWorldScene.cpp 파일을 컴파일한 HelloWorldScene.o 파일이 생성됩니다. (컴파일러에 따라서 확장자가 .o가 아닐 수도 있습니다)
컴파일 과정에서는 함수의 선언 부분(함수 호출에 대한 규격)만 있어도 컴파일이 가능합니다. (그리고 이 선언 부분을 재작성하는 것을 피하기 위해 헤더 파일(.h)로 분리하고 include 합니다)
링크는 컴파일한 오브젝트 파일(.o 파일들)을 합쳐서 하나의 실행파일로 만드는 과정입니다. 만약 링크 과정에서 모든 .o 파일을 둘러봐도 HelloWorld::scene() 함수의 정의 부분이 없으면 링크 에러가 납니다. (또한 정의가 두 개 이상 발견돼도 에러가 납니다)
링크 과정이 끝나면 그제서야 실행이 가능합니다.
질문으로 돌아가서, AppDeligate.cpp에서 HelloWorld::scene()을 호출할 수 있는 이유는, App.Deligate.cpp 에서 함수의 호출 규격을 알고 있고, 링크 과정을 거친 실행파일에 HelloWorld::scene() 함수의 정의가 포함되어 있기 때문입니다.
코드는 어려워서 모르겠고요..
질문의 요지가
main.cc
#include "file.h"
하고 main.cc 를 컴파일 할 때 file.cc 파일이 어떻게 링크가 걸리느냐는 것으로 이해하고 답변을 드립니다.
포괄적으로 컴파일이라고 하는 것은 목적코드인 .obj를 만드는 과정과 .cc 파일들을 걸어주는 링크 과정으로 나뉩니다. 좁게는 컴파일을 목적코드를 만드는 과정으로 설명하기도 합니다. 좁게 말하자면 프로그램의 번역과정은 컴파일과정과 링크과정입니다.
그런데 넓은 의미의 컴파일을 하기 위해서 다음과 같이 명시합니다.
g++ -o main main.cc file.cc
그러면 컴파일러는 file.cc가 링크가 걸릴 파일이라는 정보를 받고 링크 시에 저 파일을 연결해서 기계어 코드를 만듭니다. 정보가 없다면 기계도 적절한 처리를 할 수 없겠죠. 당연한 말이지만요....
본인 맞습니다.
인증샷
우헤헤헤... 로 대신합니다.
마지막에 결국에는 실행파일을 만들때 정보를
마지막에 결국에는 실행파일을 만들때 정보를 가지게되는군요.
답변 감사합니다.
코드를 보니까 생각나서 적어봅니다
클래스에서 static으로 변수를 지정하면. 전역적으로 사용할 수 있게 됩니다.
자세한것은 책'을 참고해 봐야할거 같습니다. ㅇ_ㅇ;;
----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.
매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.
각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com
댓글 달기