이전 포스트에서 작성한 라이브러리를 스케치에서 사용하는 방법을 알아보자.

#include <Morse.h> //라이브러리 인클루드
Morse morse(13);
void setup() {
}
void loop() {
   morse.dot(); morse.dot(); morse.dot();
   morse.dash(); morse.dash(); morse.dash();
   morse.dot(); morse.dot(); morse.dot();
   delay(3000);
}

이 파일은 원래의 스케치파일과 비교하여 몇 가지 다른 점이 있다. 먼저 라이브러리를 인클루드하기 위해서 #include <Morse.h>를 서두에 추가한 것이다. 이것으로 라이브러리에서 정의된 클래스를 이용할 수 있다. 두 번째로 클래스의 인스턴스를 다음과 같이 생성한다는 것이다.

Morse morse(13);

이것이 실행되면 Morse 클래스의 생성자가 실행되며 13이라는 핀번호를 넘겨주게 된다. 이 생성자 안에서 pinMode()함수를 실행했으므로 setup() 함수에서는 그럴 필요가 없다. 그리고 dot(), dash() 함수를 호출하기 위해서는 이 클래스 인스턴스를 매개로 해야 한다. 예를 들어서 13번 핀과 12번 핀에 LED가 연결되어 있다면 다음과 같이 하면 된다.

Morse morse(13);
Morse morse2(12);


멤버 함수 하이라이트 기능

 만약 아두이노 IDE를 사용한다면 추가로 keyword.txt 파일을 만들어서 하이라이트될 함수명을 지정해 줄 수 있다.


Morse KEYWORD1
dash KEYWORD2
dot KEYWORD2

 

각각의 줄은 함수명과 탭구분자 그리고 KEYWORD1/KEYWORD2 라는 지정어가 와야 한다. KEYWORD1은 클래스명을 지정하며 KEYWORD2 는 멤버함수임을 지정한다.

예제 파일 제공

 만약 다른 사용자들의 편의를 제공하기 위해서 예제를 제공하고 싶다면 Morse 폴더 밑에 examples 폴더를 생성한 후 그 안에 각각의 예제를 위한 폴더들을 만들고 그 안에 예제파일을 두면 된다. 이 예제들은 아두이노 IDE의 파일>예제 메뉴에 자동으로 나타난다.

#ifndef ~ #endif 전처리문의 이해

 동일한 헤더 파일(.h 파일)을 중복해서 선언하면 문법적으로 오류를 발생하게 되어 있다. 예를 들어서 MyLib.cpp 파일에서

#include “MyLib.h”
#include “MyLib.h”
....

와 같이 중복선언을 한다면 컴파일러 오류가 발생할 것이다. 사용자가 이런 식으로 작성하는 경우는 거의 없겠지만 개발자의 의도와 관계없이 이런 경우가 발생할 수도 있다. 예를 들어서 a.h 에서 b.h 를 인클루드 했는데 a.cpp 파일에서 이를 간과하고 a.h 와 b.h 둘 다 인클루드 했다면 결과적으로 b.h 는 두 번 포함되는 것이다.


 이 문제는 #ifndef _상수 ~ #endif 전처리문으로 회피할 수 있다. 전처리문은 컴파일이 수행되기 이전에 처리되며 이것의 동작은 이것으로 묶인 부분이 컴파일에 포함되려면 ‘_상수’ 가 정의되지 않은 상태여야 한다.(if not defined 가 조합된 명령어가 #ifndef 이다.)

해결책은 이전 포스트에서 언급한 바와 같이 헤더 파일 전체를 다음과 같이 이 전처리문으로 묶는 것이다.

#ifndef MYLIB_H
#define MYLIB_H
class MyLib {
   ...
};
#endif

이제는 MyLib.h 헤더파일을 아무리 중복해서 인클루드해도 오류가 발생하지 않는다. 그 원리는 맨 처음 인클루드 명령에서는 MYLIB_H라는 상수가 정의되지 않았기 때문에 #ifndef ~ #endif 안의 프로그램이 수행되는데 그 안에서는 MYLIB_H 상수가 정의된다. 즉 맨 처음 이 구문이 포함될 때 상수 MYLIB_H가 정의되므로 만약 중복되서 인클루드되는 경우가 발생하더라도 두 번째 부터는 #ifndef ~ #endif 안의 프로그램이 포함이 되지 않는 것이다.

 결과적으로 맨 처음에 수행되는  #include “MyLib.h” 문만 처리되며 그 이후의 중복되는 #inclde 명령은 처리되지 않게 되어 MyLib 클래스의 선언부가 한 번만 확장된다.



Posted by 살레시오