본문 바로가기

Studying/Computer Programs

비주얼 스튜디오 C/C++ 라이브러리 만들기

이번 포스팅에서는 마이크로소프트 비주얼 스튜디오에서 C언어 또는 C++ 라이브러리를 제작하고 사용하는 법에 대해 알아봅시다. 라이브러리는 정적 (static) 라이브러리와 동적 (dynamic) 라이브러리가 있는데요. 정적 라이브러리는 실행 파일에 함수들의 정보가 모두 들어가는 반면에, 동적 라이브러리는 프로그램이 실행되는 시점에 소환된다는 차이점이 있습니다.

 

반응형

 

비주얼 스튜디오에서는 별도의 프로젝트 유형을 선택하여 이러한 라이브러리들을 만들고 사용할 수 있습니다. 여기서는 비주얼 스튜디오 커뮤니티 2019 버전을 기준으로 이야기하며, 소스 코드로부터 프로그램을 만드는것과 관련된 기본적인 내용들은 다음 포스팅에 소개되어 있습니다.

 

 

비주얼 스튜디오 C/C++ 콘솔 프로그램 만들기

여기서는 마이크로소프트의 통합 개발환경인 비주얼 스튜디오를 이용해서, C언어 또는 C++ 콘솔 프로그램을 만드는 법에 대해서 알아봅시다. 콘솔 프로그램이란 문자만으로 이루어진 인터페이

swstar.tistory.com

 

라이브러리를 만들기 위해서는 먼저 새 프로젝트를 열어야 합니다. 왼쪽 상단의 파일 > 새로 만들기 > 프로젝트를 선택합시다.

 

screenshot of Visual Studio Community 2019, showing the new project menu in the main screen

 

그러면 프로젝트의 유형을 선택할 수 있는 창이 뜨는데요. 정적 라이브러리와 동적 (Dynamic-Link Library, 줄여서 DLL) 라이브러리 중 하나를 선택하면 되겠습니다.

 

screenshot of Visual Studio Community 2019, showing project template selection

 

정적 라이브러리

구현하고자 하는 기능을 고려해서 프로젝트의 이름을 적당히 짓고, 생성 버튼을 클릭합니다.

 

screenshot of Visual Studio Community 2019, showing solution name selection for a static library

 

기존에 작성해둔 소스 파일이나 헤더 파일이 있다면, 프로젝트가 위치한 디렉토리에 복사해 줍니다.

 

서브디렉토리나 다른 디렉토리에 있는 헤더 파일을 사용하기 위해서는 프로젝트 속성에서 이들의 위치를 별도로 알려줘야 합니다. C/C++의 일반 (General) 항목에서 헤더 파일들이 있는 디렉토리를 추가할 수 있습니다.

 

screenshot of windows explorer, showing source and header files to be added to a Visual Studio library

 

라이브러리를 위한 새 프로젝트를 이렇게 만들고 나면, 솔루션 탐색기를 통해서 소스 및 헤더 파일들을 새로 만들거나 추가할 수 있습니다.

 

screenshot of Visual Studio Community 2019, showing an option to add source and header files to the project

 

소스파일과 헤더 파일들을 추가하고 나면, 왼쪽 상단 탭을 통해서 이 파일들을 선택하고 내용을 수정할 수 있죠.

 

그 위에 있는 드롭다운 메뉴를 통해 32비트 어플리케이션을 위한 라이브러리인지, 아니면 64비트 어플리케이션을 위한것인지를 선택할 수 있습니다.

 

screenshot of Visual Studio Community 2019, showing editor for source and header files

 

비주얼 스튜디오에서는 사전 컴파일 (Precompiled) 헤더라는 기능을 제공하고 있는데요. 말 그대로 다른 소스 파일보다 먼저 컴파일하고 싶은 내용을 별도의 헤더 파일에 넣을 수 있고, 새 프로젝트를 시작하면 pch.h 라는 이름의 헤더 파일로 등장합니다.

 

이는 라이브러리의 성능을 향상시키기 위한 옵션사항이기 때문에, 여기서는 쓰지 않는걸로 하겠습니다. 프로젝트 이름을 우클릭 하고 속성 (properties)을 선택한 뒤, C/C++의 Precompiled Headers 항목에서 사용안함을 선택하면 되겠습니다.

 

screenshot of Visual Studio Community 2019, showing options regarding pre-compiled header in project property

 

소스 파일과 헤더 파일들이 완성되고 나면, 빌드 탭에서 솔루션 빌드를 클릭합시다. 코드에 문제가 없다면, 정적 라이브러리를 빌드할 수 있습니다.

 

screenshot of Visual Studio Community 2019, showing the build project menu in the main screen

 

윈도우 탐색기에서 .lib 확장자를 가진 정적 라이브러리 파일을 확인할 수 있습니다.

 

screenshot of windows explorer, showing a static library created in Visual Studio project

 

정적 라이브러리를 만들었으니, 이제 사용하는 방법을 알아봅시다. 여기서는 C++ 콘솔 어플리케이션의 경우를 소개합니다. 새로운 프로그램을 위해서 프로젝트를 새로 만들면 되는데, 이때는 콘솔 어플리케이션 (Console App)을 선택해야 합니다.

 

라이브러리에 포함된 함수들을 호출하는 소스 코드를 일단 작성하고 나면, 오류 메시지가 뜰 텐데요. 이는 컴파일러가 라이브러리의 위치와 함수의 프로토타입을 알 수 없어서 생기는 문제입니다. 이를 해결하기 위해 앞에서 만든 라이브러리의 프로젝트를 현재 솔루션에 먼저 추가해줘야 합니다.

 

솔루션 탐색기에서 솔루션 이름을 우클릭하면, 기존의 프로젝트를 추가할 수 있는 옵션이 등장합니다.

 

screenshot of Visual Studio Community 2019, showing editor for source and header files of Console application

 

앞서 만들었던 정적 라이브러리 프로젝트에 대한 정보가 포함된 .vcxproj 파일을 선택해줍시다. 그러면 해당 프로젝트가 추가되어 솔루션 탐색기에서 확인할 수 있습니다.

 

screenshot of Visual Studio Community 2019, showing addition of existing project to a new one for Console App

 

그 다음은 현재 프로젝트에서 라이브러리 프로젝트를 참조할 수 있게 설정해줘야 합니다. 현재 프로젝트 이름을 우클릭하면 참조 (Reference)를 추가할 수 있는 옵션이 뜹니다.

 

screenshot of Visual Studio Community 2019, showing an option to add refernce from the solution explorer

 

정적 라이브러리를 위한 프로젝트 옆의 사각형에 체크를 하고, 확인을 클릭합니다.

 

screenshot of Visual Studio Community 2019, showing addition of refernce to the static library

 

마지막 단계는 라이브러리의 헤더 파일들이 어디에 있는지를 알려주는 것인데요. 프로젝트 속성에 있는 C/C++의 일반 탭에서 헤더파일이 있는 디렉토리를 추가해줄 수 있습니다.

 

screenshot of Visual Studio Community 2019, showing addition of directory for header files in the project property

 

이제 상단에 있는 빌드 > 솔루션 빌드를 클릭하여, 프로그램을 만들 수 있습니다.

 

프로그램을 실행하기 위해서는 디버그 > 디버깅하지 않고 시작을 선택합니다.

 

screenshot of Visual Studio Community 2019, showing button to start without debuggging

 

콘솔 어플리케이션의 경우, 터미널 창이 열리면서 실행결과가 나오는데요. 정적 라이브러리에서 정의한 대로 함수가 호출되는 것을 확인할 수 있습니다.

 

screenshot of Visual Studio Community 2019, showing execution of a console application with a static library linked

 

출처 : docs.microsoft.com

 

Walkthrough: Create and use a static library (C++)

Use C++ to create a static library (.lib) in Visual Studio.

docs.microsoft.com

 

동적 라이브러리

동적 DLL 라이브러리의 경우, 함수의 프로토타입이나 클래스 등을 선언할 때 __declspec(dllexport)__declspec(dllimport) 키워드들이 필요합니다. 지금은 라이브러리를 만들고 있기 때문에, 함수들을 DLL 파일로 내보내기 위한 __declspec(dllexport) 키워드를 붙여야 합니다. 반면에 동적 라이브러리를 링크한 프로그램을 작성하는경우, DLL 파일로부터 함수의 정보를 가져오기 위한 __declspec(dllimport) 키워드가 필요하죠.

 

다음과 같이 mylib.h 라는 헤더 파일과 mylib.c 라는 소스 파일로부터 동적 라이브러리를 만드는 경우를 상정해 봅시다.

 

mylib.h

#ifndef MYLIB_H
#define MYLIB_H

#include <windows.h>

#ifdef DLL_TEST01_EXPORTS
  #define DLL_TEST01_API __declspec(dllexport)
#else
  #define DLL_TEST01_API __declspec(dllimport)
#endif

#undef __WRAP_CXX_INI
#undef __WRAP_CXX_FIN
#ifdef __cplusplus
  #define __WRAP_CXX_INI extern "C" {
  #define __WRAP_CXX_FIN }
#else
  #define __WRAP_CXX_INI /* empty */
  #define __WRAP_CXX_FIN /* empty */
#endif

__WRAP_CXX_INI

DLL_TEST01_API double Function(double x);

__WRAP_CXX_FIN

#endif

 

mylib.c

#include <mylib.h>

double Function(double x) {
    double ret;

    /* ... 함수의 내용 ...
     * ret의 값 정의 */

    return ret;
}

 

소스 파일은 정적 라이브러리를 빌드할 때와 다르지 않습니다만, 헤더 파일의 경우에는 위에 언급한대로 __declspec 키워드들을 추가해야 합니다. 라이브러리를 제작할때와 사용할 때 모두 동일한 헤더 파일을 사용하기 위해서, 별도의 장치를 마련할 필요가 있는데요. 예시로 나오는 헤더파일에서는 전처리 식별자인 DLL_TEST01_EXPORTSDLL_TEST01_API가 그 역할을 합니다.

 

먼저 DLL_TEST01_EXPORTS와 관련된 전처리 조건문이 있는것을 볼 수 있습니다. 만약 DLL_TEST01_EXPORTS가 정의되어 있다면, 함수의 프로토타입 앞에 붙어있는 DLL_TEST01_API에는 __declspec(dllexport) 키워드가 대입됩니다. 그렇지 않다면, __declspec(dllimport) 키워드가 들어가죠.

 

이제 남은 단계는 DLL_TEST01_API 식별자에 __declspec(dllexport) 키워드가 들어가도록, DLL_TEST01_EXPORTS 식별자를 정의해주는 것입니다. 프로젝트 속성을 열어서 C/C++의 전처리기 항목에서 전처리 식별자를 추가해 주면 되겠습니다.

 

screenshot of Visual Studio Community 2019, showing options regarding preprocessor in DLL project property

 

전처리 식별자를 정의한 다음 프로젝트를 빌드하면, DLL 동적 라이브러리가 생성됩니다.

 

이제 C/C++ 프로그램에 동적 DLL 라이브러리를 연결하여 실행하는 법에 대해 알아봅시다. 헤더 파일이 포함된 디렉토리를 추가하는 과정은 정적 라이브러리의 경우와 동일합니다. 동적 라이브러리를 빌드하고 나면 .dll 파일과 .lib 파일이 같이 생성되는데, .lib 파일의 디렉토리를 알려줘야 현재 프로젝트에서 프로그램을 빌드할 수 있습니다.

 

screenshot of Visual Studio Community 2019, showing addition of directory for library files in the project property

 

다음 단계는 현재 작성하는 프로그램이 라이브러리에 의존한다는 점을 알려주는 것입니다. 링커의 입력 (Input) 탭에서 어떤 라이브러리에 의존하는지를 지정할 수 있는데요. 앞서 제작했던 라이브러리의 .lib 파일을 추가해주면 됩니다.

 

screenshot of Visual Studio Community 2019, showing addition of dependencies in the project property

 

동적 라이브러리는 프로그램을 실행하는 단계에서 소환된다고 앞에서 언급했었는데요. 동적 라이브러리를 제대로 링크하려면, DLL 파일을 실행파일이 있는 위치로 가져다줘야 합니다. 이를 위해서 빌드 이벤트를 설정할 수 있는데, 여기서 필요한것은 코드로부터 프로그램을 빌드하고 난 뒤에, DLL파일을 복사해오는 포스트-빌드 (Post-Build) 이벤트입니다.

 

프로젝트 속성에서 빌드 이벤트의 포스트-빌드 이벤트 탭을 선택하고, DLL파일을 복사하는 명령어를 추가해 주면 되겠습니다. 이 때 현재 프로젝트 디렉토리가 저장된 ProjectDir 및 실행파일과 출력파일 등이 생성되는 디렉토리가 저장된 OutDir 등의 환경변수들을 활용하면 좋습니다.

 

screenshot of Visual Studio Community 2019, showing addition of post-build event in the project property

 

동적 라이브러리를 연결하기 위한 절차를 마친 뒤, 프로젝트를 빌드하고 실행하면 되겠습니다.

 

출처 : docs.microsoft.com

 

Walkthrough: Create and use your own Dynamic Link Library (C++)

Use C++ to create a Windows dynamic-link library (DLL) in Visual Studio.

docs.microsoft.com

 

리눅스나 유닉스에서 C언어 라이브러리를 만들고 사용하는 법에 대해서는 다음 포스팅을 참고하면 도움이 되리라 생각합니다.

 

 

C언어 라이브러리 만들기

자주 쓰는 함수들을 라이브러리 형태로 만들어 두면, 프로그램을 짤 때 편리합니다. 오브젝트 파일로부터 라이브러리를 제작하고, 이를 헤더 파일과 함께 이용하는 방법을 알아볼텐데요. 만약

swstar.tistory.com