공유 라이브러리 생성
다음 섹션에서는 공유 라이브러리를 생성할 때 고려해야 할 몇 가지 사항을 나열합니다.
공유 라이브러리의 심볼 사용
애플리케이션이나 다른 라이브러리와 같은 클라이언트에서 사용하기 위해 공유 라이브러리에 포함된 심볼(함수, 변수 또는 클래스)은 특별한 방식으로 표시되어야 합니다. 이러한 심볼을 공용 심볼이라고 하며, 외부로 내보내지거나 공개적으로 볼 수 있게 됩니다.
나머지 심볼은 외부에서 볼 수 없어야 합니다. 대부분의 플랫폼에서 컴파일러는 기본적으로 이러한 심볼을 숨깁니다. 일부 플랫폼에서는 이러한 심볼을 숨기기 위해 특별한 컴파일러 옵션이 필요합니다.
공유 라이브러리를 컴파일할 때는 내보내도록 표시해야 합니다. 클라이언트에서 공유 라이브러리를 사용하려면 일부 플랫폼에서는 특별한 가져오기 선언도 필요할 수 있습니다.
대상 플랫폼에 따라 Qt는 필요한 정의를 포함하는 특수 매크로를 제공합니다:
- Q_DECL_EXPORT 공유 라이브러리를 컴파일할 때 사용되는 심볼의 선언에 반드시 추가되어야 합니다.
- Q_DECL_IMPORT 공유 라이브러리를 사용하는 클라이언트를 컴파일할 때 사용되는 심볼의 선언에는 다음을 추가해야 합니다.
이제 공유 라이브러리 자체를 컴파일하든, 아니면 공유 라이브러리를 사용하는 클라이언트만 컴파일하든 상관없이 올바른 매크로가 호출되도록 해야 합니다. 일반적으로 이는 특수한 헤더를 추가함으로써 해결할 수 있습니다.
mysharedlib라는 공유 라이브러리를 만들려고 한다고 가정해 봅시다. 이 라이브러리를 위한 특수 헤더인 mysharedlib_global.h 는 다음과 같습니다:
#include <QtCore/QtGlobal>
#if defined(MYSHAREDLIB_LIBRARY)
# define MYSHAREDLIB_EXPORT Q_DECL_EXPORT
#else
# define MYSHAREDLIB_EXPORT Q_DECL_IMPORT
#endif라이브러리의 각 헤더 파일에서 다음을 지정합니다:
#include "mysharedlib_global.h"
MYSHAREDLIB_EXPORT void foo();
class MYSHAREDLIB_EXPORT MyClass...그런 다음 라이브러리 자체를 빌드할 때 컴파일러에 대해 ` MYSHAREDLIB_LIBRARY `가 정의되도록 해야 합니다. 이는 라이브러리의 빌드 시스템에서 처리됩니다. CMake를 사용하는 경우, 공유 라이브러리 타깃을 다음과 같이 확장합니다:
target_compile_definitions(mysharedlib PRIVATE MYSHAREDLIB_LIBRARY)qmake를 사용하는 경우,
DEFINES += MYSHAREDLIB_LIBRARY.pro 를 추가합니다.
참고: Qt Creator 와 Qt VS Tools 의 라이브러리 마법사는 이러한 설정을 자동으로 처리해 주는 기본 템플릿을 제공합니다.
헤더 파일 관련 고려 사항
일반적으로 클라이언트는 공유 라이브러리의 공개 헤더 파일만 포함합니다. 이러한 라이브러리는 배포 시 다른 위치에 설치될 수 있습니다. 따라서 공유 라이브러리를 빌드할 때 사용된 다른 내부 헤더 파일은 제외하는 것이 중요합니다.
예를 들어, 라이브러리가 하드웨어 장치를 래핑하고 타사 라이브러리에서 제공하는 해당 장치에 대한 핸들을 포함하는 클래스를 제공할 수 있습니다:
#include <footronics/device.h>
class MyDevice {
private:
FOOTRONICS_DEVICE_HANDLE handle;
};집합 상속이나 다중 상속을 사용할 때 Qt Widgets Designer 에 의해 생성된 폼에서도 유사한 상황이 발생합니다:
#include "ui_widget.h"
class MyWidget : public QWidget {
private:
Ui::MyWidget m_ui;
};라이브러리를 배포할 때는 footronics/device.h 또는 ui_widget.h 와 같은 내부 헤더 파일에 대한 의존성이 없어야 합니다.
이는 다양한 C++ 프로그래밍 서적에 설명된 ‘구현체 포인터(Pointer to implementation )’ 관례를 활용함으로써 피할 수 있습니다. 값 세미오틱을 갖는 클래스의 경우, ` QSharedDataPointer`를 사용하는 것을 고려해 보십시오.
바이너리 호환성
공유 라이브러리를 불러오는 클라이언트가 올바르게 작동하려면, 사용되는 클래스의 메모리 레이아웃이 클라이언트를 컴파일할 때 사용된 라이브러리 버전의 메모리 레이아웃과 정확히 일치해야 합니다. 즉, 런타임에 클라이언트가 찾아낸 라이브러리는 컴파일 시에 사용된 버전과 이진 호환되어야 합니다.
클라이언트가 필요한 모든 라이브러리를 함께 제공하는 독립형 소프트웨어 패키지인 경우, 이는 대개 문제가 되지 않습니다.
그러나 클라이언트 애플리케이션이 다른 설치 패키지나 운영 체제에 속한 공유 라이브러리에 의존하는 경우, 공유 라이브러리에 대한 버전 관리 체계를 고려하고 이진 호환성을 어느 수준에서 유지할지 결정해야 합니다. 예를 들어, 동일한 주요 버전 번호를 가진 Qt 라이브러리들은 이진 호환성이 보장됩니다.
바이너리 호환성을 유지하려면 클래스에 가할 수 있는 변경 사항에 몇 가지 제한이 따릅니다. 이에 대한 자세한 설명은 KDE - Policies/Binary Compatibility Issues With C++에서 확인할 수 있습니다. 이러한 문제들은 라이브러리 설계 초기 단계부터 고려해야 합니다. 가능한 한 ‘정보 은닉’ 원칙과 ‘구현 포인터’ 기법을 사용할 것을 권장합니다.
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.