c++ rpath 사용법 - 동적 라이브러리와 정적 라이브러리를 사용하는 경우



9 Answers

다른 사람들은 정적 라이브러리가 무엇인지에 대해 적절히 설명했지만 적어도 Windows에서는 정적 라이브러리를 사용할 때의 몇 가지주의 사항을 지적하고자합니다.

  • 싱글 톤 : 무언가가 전역 / 정적 및 고유 일 필요가있는 경우 정적 라이브러리에 넣는 것에 매우주의하십시오. 해당 정적 라이브러리에 대해 여러 DLL이 연결되어 있으면 각각은 자체 소유의 복사본을 갖게됩니다. 그러나 응용 프로그램이 사용자 지정 DLL이없는 단일 EXE 인 경우 문제가되지 않을 수 있습니다.

  • 참조되지 않은 코드 제거 : 정적 라이브러리에 연결할 때 DLL / EXE에서 참조하는 정적 라이브러리 부분 만 DLL / EXE에 연결됩니다.

    예를 들어 mylib.liba.objb.obj 있고 DLL / EXE가 a.obj 함수 또는 변수 만 참조하면 b.obj 전체가 링커에 의해 삭제됩니다. b.obj 에 전역 / 정적 객체가 포함되어 있으면 해당 생성자와 소멸자가 실행되지 않습니다. 이러한 생성자 / 소멸자가 부작용이있는 경우 해당 부재로 인해 실망 할 수 있습니다.

    마찬가지로 정적 라이브러리에 특수 진입 점이 포함되어 있으면 실제로 포함되어 있는지주의해야합니다. 임베디드 프로그래밍 (예 : Windows가 아님)의 예는 특정 주소에 있다고 표시된 인터럽트 핸들러입니다. 또한 인터럽트 핸들러를 진입 점으로 표시하여 버려지지 않도록해야합니다.

    이것의 또 다른 결과는 미확인 참조로 인해 완전히 사용할 수없는 객체 파일을 정적 라이브러리에 포함 할 수 있지만 이러한 객체 파일에서 함수 나 변수를 참조 할 때까지 링커 오류가 발생하지 않습니다. 라이브러리를 작성한 후 오랜 시간이 걸릴 수 있습니다.

  • 디버그 기호 : 각 정적 라이브러리에 대해 별도의 PDB가 필요하거나 디버그 기호를 DLL / EXE 용 PDB에 넣을 수 있도록 개체 파일에 배치 할 수 있습니다. Visual C ++ 문서는 필요한 옵션을 설명 합니다 .

  • RTTI : 하나의 정적 라이브러리를 여러 DLL에 연결하면 동일한 클래스에 대해 여러 개의 type_info 객체가 생길 수 있습니다. 프로그램이 type_info 가 "singleton"데이터이고 &typeid() 또는 type_info::before() 사용한다고 가정하면 바람직하지 않고 놀라운 결과를 얻을 수 있습니다.

실행 라이브러리는 일반

C ++에서 클래스 라이브러리를 만들 때 동적 (.dll) 라이브러리와 정적 (.lib) 라이브러리 중에서 선택할 수 있습니다. 그 (것)들 사이 다름은 무엇이고 언제 어느 것을 사용하는 것이 적당합니까?




정적 대 동적 라이브러리 (정적 파일은 여러 다른 실행 파일 간의 코드 공유를 허용하는 하나의 큰 바이너리와 동적 라이브러리의 모든 것을 묶음)와 기술적 인 관련성 외에도 법적으로 의미가 있습니다.

예를 들어, LGPL 라이선스 코드를 사용하고 LGPL 라이브러리에 정적으로 링크하여 (따라서 하나의 큰 바이너리를 생성하는 경우) 코드는 자동으로 Open Sourced ( 자유대로 자유) LGPL 코드가됩니다. 공유 객체에 링크하면 LGPL 라이브러리 자체에 개선점 / 버그 수정 사항 만 LGPL에 필요합니다.

예를 들어 모바일 애플리케이션을 컴파일하는 방법을 결정할 때 이것은 훨씬 더 중요한 문제가됩니다 (안드로이드에서는 정적 대 동적 중 하나를 선택할 수 있습니다. 그렇지 않은 경우 iOS에서는 항상 정적입니다).




C ++ 프로그램은 두 단계로 작성됩니다.

  1. 컴파일 - 객체 코드 (.obj) 생성
  2. 링크 - 실행 코드 (.exe 또는 .dll) 생성

정적 라이브러리 (.lib)는 .obj 파일의 묶음 일 뿐이므로 완전한 프로그램은 아닙니다. 프로그램을 구축하는 두 번째 (연결) 단계를 거치지 않았습니다. 반면에 Dll은 exe와 비슷하므로 완전한 프로그램입니다.

정적 라이브러리를 빌드하면 아직 링크되지 않으므로 정적 라이브러리의 사용자는 사용했던 것과 동일한 컴파일러를 사용해야합니다 (g ++을 사용하는 경우 g ++을 사용해야 함).

대신 dll을 빌드하고 correctly 빌드하면 사용하는 컴파일러에 관계없이 모든 소비자가 사용할 수있는 완전한 프로그램을 빌드했습니다. 크로스 컴파일러 호환성이 필요한 경우에는 dll에서 내 보내면 몇 가지 제한 사항이 있습니다.




정적 라이브러리가 클라이언트로 컴파일됩니다. .lib는 컴파일 할 때 사용되며 라이브러리의 내용은 소비 가능한 실행 파일의 일부가됩니다.

동적 라이브러리는 런타임에로드되고 클라이언트 실행 파일로 컴파일되지 않습니다. 동적 라이브러리는 다중 클라이언트 실행 파일이 DLL을로드하고 해당 기능을 활용할 수 있으므로보다 융통성이 있습니다. 또한 클라이언트 코드의 전체 크기와 유지 관리 가능성을 최소한으로 유지합니다.




" 공유 라이브러리 작성법"에 대한 Ulrich Drepper의 논문은 공유 라이브러리 를 최대한 활용하는 방법이나 DSO (Dynamic Shared Objects)라고 불리는 것을 자세히 설명하는 훌륭한 자료입니다. ELF 바이너리 형식의 공유 라이브러리에 초점을 맞추었지만 일부 토론은 Windows DLL에도 적합합니다.




정말 큰 프로젝트에서 초기로드 시간에 라이브러리를 만들거나, 라이브러리를 한 번에 또는 다른 링크로 만들 것인지 결정해야합니다. 컴파일러가 필요로하는만큼 링크를 오래 걸릴 것인지 결정해야합니다. 글 머리 기호를 물고 앞에 붙이거나 동적 링커가 로딩 할 때 할 수 있습니까?




라이브러리가 정적 인 경우 링크 타임에 코드가 실행 파일과 링크됩니다. 동적 경로를 선택했을 때보 다 실행 파일이 커집니다.

라이브러리가 동적이면 링크시 필요한 메소드에 대한 참조가 실행 파일에 내장됩니다. 즉, 실행 파일과 동적 라이브러리를 제공해야합니다. 또한 라이브러리의 코드에 대한 공유 액세스가 안전한지, 다른 것들 중에서 선호하는로드 주소인지 여부를 고려해야합니다.

정적 라이브러리로 살 수있는 경우 정적 라이브러리로 이동하십시오.




임베디드 프로젝트 또는 특수 플랫폼 정적 라이브러리에 대한 작업 만 수행하는 유일한 방법 인 경우에도 응용 프로그램으로 컴파일하는 번거 로움이 적습니다. 또한 모든 것을 포함하는 프로젝트와 메이크 파일을 가지고 있으면 더 행복하게 살 수 있습니다.




큰 코드베이스를 가지고 있다면 하위 라이브러리 (예 : Utils 또는 Gui 프레임 워크) 위에 빌드 된 모든 관리 가능한 라이브러리로 분할하여 정적 라이브러리로 만들 겠다는 일반적인 경험을 줄 것입니다. 다이나믹 라이브러리는 실제로 당신에게 아무 것도 사지 않으며 놀라움이 적습니다. 예를 들어 싱글 톤 인스턴스가 하나만있을 것입니다.

나머지 코드베이스 (예 : 타사 라이브러리)와 완전히 별도의 라이브러리를 가지고 있다면 dll로 만드십시오. 라이브러리가 LGPL 인 경우 라이선스 조건으로 인해 dll을 사용해야 할 수도 있습니다.




Related