임베디드 레시피

Egloos | Log-in





씨 언어에서 씨 플러스플러스 함수를 콜하는 방법은?

뭘 알아야 이해를 하지

임베디드 시스템은 예전부터 대부분 씨 언어를 사용해서 프로그램을 만들어 왔답니다. 최근 들어 시피유, 메모리, 배터리 등 기술이 점점 발달하면서 씨 언어 하나만 사용하지 않고 씨 플러스 플러스언어나 자바 언어까지 사용해서 프로그램을 개발한답니다. 앞에서 잠깐 암 어셈블러에서 씨 언어 메인 함수 콜 하는 방법을 알아 봤어요. 암 어셈블러에서 씨 언어 메인 함수 콜하는 방법은 그리 어렵지 않았답니다. 
  


 
암 어셈블러에서 씨 언어 메인 함수 콜하는 방법이랍니다.
예제를 살펴보겠습니다.
 
[암 어셈블러에서 씨 언어 메인 함수 호출]


 
Startup.s 파일에서 .global main(b-1)이라고 선언을 해 주고 main(g-1)으로 call하면 됩니다. 간단하죠. 여기서 주의하셔야 할 내용은 대소문자랍니다. Startup.s 파일의 두 군데(b-1,g-1)에서 대소문자를 썩어서 사용했다면 main.c에서 main함수 이름도 Startup.s 파일에서 지정한 이름과 동일하게 작성을 해야 하죠.
 
그럼 이제부터는 씨 언어에서 씨 플러스플러스 함수를 콜하는 방법에 대해 알아 보려고 해요. 그 전에 잠깐 살펴보야 될 내용이 씨 언어와 씨 플러스플러스 언어와의 차이점에 조금 아셔야 해요. 그래야 씨 언어에서 씨 플러스 플러스 함수 콜을 자유롭게 할 수가 있답니다.
씨 플러스플러스의 강점은 계층(class)을 이용할 수 있다는 점입니다. 즉, 모듈과 캡슐화가 잘 되어진 언어라는 거죠.
 
예제를 살펴봐요.

 
객체와 객체의 실체에 대해 알아보아요.
 soto_struct(f-2), c_plus_plus(m-4)는 객체이고, 객체의 실체는 int star;(b-2), cpp_data(c-2); 이랍니다. soto_struct에는 데이타와 함수까지 모두 포함되어 있네요. 이렇게 데이타와 함수를 포함하는 방식은 private와 public가 있어요. private의 경우는 객체의 외부에서는 참조할 수 없어요. 하지만 public의 경우는 객체의 외부에서 참조할 수가 있답니다.
 
c_plus_plus.cpp_data=10;
soto_struct.han();
soto_struct.byul_func();
 
class안의 두 함수 void han(void); (d-2) ,  void byul_func(void); (e-2)는 프로토타입이라고 해요. 이렇게 선언된 함수 자체를 정의(g-2, i-2)할 수가 있답니다. 여기서 one_class의 멤버 함수임을 나타낼 때 스코프 해상도 연사자(scope resolution operator)인 "::"을 사용한답니다.
 
간단하게 씨 플러스플러스를 살펴봤으니 씨 언어와 연결을 해 보도록 하죠.
 
  a-3와 같이 외부 함수임을 선언하고, b-3와 같이 콜 해 주면 우선 프로그램 상에서는 끝났어요. 다음으로 해 줘야 될 사항이 makefile에서 수정을 해 주셔야 해요.
우선 main.c는 arm-elf-gcc를 사용하면 되지만 cpp_func.cpp는 arm-elf-c++을 사용해야 되죠.
 
 
   
[컴파일 실행]
./sources/main.c:15: undefined reference to `extern_func'
collect2: ld returned 1 exit status
make: *** [general.elf] Error 1
 
정상적으로 컴파일이 되지 않고 에러가 발생했는데 왜 그를까요? 정말 `extern_func' 함수가 정의되지 않아서 그럴까요?
문제의 해답을 찾기 위해서는 다음과 같이 컴파일을 해 보세요.
CMD> arm-elf-gcc -S main.c
CMD> arm-elf-c++ -S cpp_func.cpp
컴파일이 되고 나면 main.s, cpp_func.s 라는 파일이 만들어진답니다.  -S라는 옵션은 어셈블리어 파일로 만들어 준답니다. 두 개의 파일에서 extern_func를 찾아보면 서로의 이름이 다르다는 것을 알수가 있어요.
 
main.s        -->  bl extern_func
cpp_func.s  --> _Z11extern_funcv:
 
이유는 서로의 컴파일러가 다르다보니 레이블 생성도 다르게 생성된답니다. 이 문제를 해결하기 위해서는 컴파일러를 통일 할 필요가 있어요. arm-elf-c++은 일반 씨 언어 컴파일도 가능하니 makefile에서 ARMCC    = $(PRE)-c++ 부분만 수정하고 다시 컴파일을 하면 된답니다.
 
CMD> make
arm-elf-size general.elf
   text    data     bss     dec     hex   filename
 1060    52       8     1120    460   general.elf
 
이왕 씨 언어에서 씨 플러스 플러스 함수 콜하는 방법을 알아 봤으니 어셈블러에서 어셈블러 함수 콜하는 것과 씨 플러스플러스 언어에서 씨 언어 함수 콜하는 방법까지 모두 알아보도록 할께요.
어셈블러에서 어셈블러 함수 콜하는 방법을 소개할께요.
 

  
  
Startup.s 파일에서는 mmulib.s 파일에 있는 레이블 이름만 콜(a-4)하면 되고, mmulib.s 파일에서는 레이블 이름을 선언(b-4)해 주고, 레이블 지정(c-4)한 다음 내용 내용을 작성하면 됩니다.
 
이제 makefile을 살펴보죠.

 
   
마지막으로 씨 플러스플러스에서 씨 함수를 콜하는 방법을 알아보죠.


   
a-5와 같이 외부 함수를 선언하고, b-5에서 c 함수를 콜해주면 우선 프로그램 상에서는 끝났어요. 다음으로 해 줘야 될 사항이 makefile에서 수정을 해 주셔야 해요.
위에 있는 예제도 보시다 시피 컴파일을 하면 에러가 발생합니다. 그래서 이번의 경우는 cpp_fucn.cpp파일이 c_func.c파일의 함수를 못 찾으니 c_func.c파일이름을 c_func.cpp 파일이름으로 바꿔서 컴파일을 하면 되요.

   

 

by 히언 | 2010/06/22 22:51 | SOTO Story | 트랙백 | 핑백(1) | 덧글(8)

Linked at 친절한 임베디드 시스템 개발자.. at 2010/06/22 22:53

... sp; 304 씨 언어에서 변수는 어디에 저장 되나요? 305 씨 언어에서 씨 플러스플러스 함수를 콜하는 방법은? 306 스케트(scatter) 파일이 뭐죠? 307 ... more

Commented by Ruring at 2010/06/23 17:57
잘읽고 갑니다욤~
Commented by soto at 2010/06/23 20:55
넹..^^;
감사합니다.
Commented by Joy at 2010/06/24 15:44
soto님은... 성격도 엄청 깔끔하실 듯 해요..
늘 감사합니다. ^^
Commented by soto at 2010/06/27 20:47
앗..저를 너무 과대 평가하신건 아닌지 모르겠네요.
어쨌든 더 열심해 해 달라는 의미로 생각할게요.
감사합니다. ^^
Commented by at 2010/06/24 15:55
항상 잘 보고 갑니다. 요즘은 축구가 대세라서... 그냥 읽고만 갑니다. ㅋㅋ
Commented by soto at 2010/06/27 20:49
저도 축구 광 팬이라..
이번 달은 글쓰는데 집중이 안되네요. ^^
Commented by Ruring at 2010/06/25 09:42
트윗을 알려주세요 그리고! 책나오나요?
첫책은 soto님이 보관하시고 두번째책이라도 +_+
첫책이라도좋고 =-=
어쨋든 =-= 싸인해서 주세요 +_+!
입금은 해드립니담~
Commented by soto at 2010/06/27 20:55
우앗...이렇게 감사할때가~~~!
참고할게요.
즐거운 주말 저녁 되세요. ^^
※ 이 포스트는 더 이상 덧글을 남길 수 없습니다.

◀ 이전 페이지          다음 페이지 ▶