문제

단순히 라이브러리와 연결하여 리소스를 정적 ​​라이브러리에 구축하고 재사용할 수 있습니까?

나는 주로 리소스에 액세스하는 라이브러리의 함수를 호출하는 경우에 대해 생각하고 있습니다.

도움이 되었습니까?

해결책

할 수는 있지만 매우 고통 스럽습니다. 단순히 정적 라이브러리와 연결하여 할 수 없습니다.

이것을 고려하십시오 : 자원은 Exe 또는 DLL에 포함됩니다. 정적 라이브러리의 일부 코드가 호출 (예 : Loadicon을 호출하면 EXE 또는 DLL에서 연결된 리소스를 얻을 수 있습니다.

따라서 정적 라이브러리에 리소스를 사용할 수 있어야하는 경우 몇 가지 옵션이 있습니다.

  1. 라이브러리가 즉석에서 구축 한 다음 사용할 수 있습니다 (예 : CreateDialogIndirect. Raymond Chen 's를 참조하십시오 "런타임에 대화 템플릿 구축".
  2. 라이브러리에 간단한 배열로 내장 할 수 있습니다 (즉) char my_dialog_resource[] = { .... };, 그런 다음 사용 (예 :) CreateDialogIndirect. 아마도 .RES 파일 .CPP 파일.
  3. 리소스 스크립트로 LIB 파일을 배송 할 수 있습니다 (.RC 파일) 및 해당 헤더 파일. 당신은 그때 #include 관련성이 있습니다. LIB가 사용하려면 다양한 리소스 ID를 예약해야하므로 기본 EXE 또는 DLL과 충돌하지 않도록해야합니다. 이것이 정적 라이브러리로 사용될 때 MFC가하는 일입니다. 또는 String Resource ID를 사용할 수 있습니다 (이것은 작동하지 않습니다. STRINGTABLE 자원).
  4. 정적 라이브러리는 별도의 리소스 DLL과 함께 배송 할 수 있습니다.

다른 팁

Visual C++(2008)의 정적 라이브러리에서 리소스(이미지, 대화 상자 등)를 사용하기 위해 수행해야 할 유일한 작업은 다음과 같습니다. 정적 라이브러리의 관련 .res 파일을 포함합니다. 당신의 프로젝트에서.이는 "프로젝트 설정/링커/입력/추가 종속성"에서 수행할 수 있습니다.

이 솔루션을 사용하면 정적 라이브러리의 리소스가 .exe로 압축되므로 추가 DLL이 필요하지 않습니다.안타깝게도 Visual Studio에서는 .lib 파일처럼 .res 파일을 자동으로 포함하지 않지만("프로젝트 종속성" 기능을 사용하는 경우) 이 작은 추가 단계는 허용될 수 있다고 생각합니다.

저는 이 솔루션을 오랫동안 찾아보았는데, 이제 그것이 그렇게 간단하다는 사실에 놀랐습니다.유일한 문제는 그것이 완전히 문서화되지 않았다는 것입니다.

방금 MS Visual Studio Compiler와 함께 이것을 살펴 보았습니다. 우리는 일부 레거시 프로젝트를 DLLS에서 정적 라이브러리로 변환했습니다. 이 DLL 중 일부에는 대화 상자 또는 문자열 자원이 포함되어 있습니다. "TextInclude"메커니즘을 통해 기본 응용 프로그램의 RC 스크립트 파일에 포함 시켜이 DLL에 대한 .rc 스크립트를 기본 응용 프로그램으로 컴파일 할 수있었습니다. RC 파일을 직접 편집 하여이 작업을 수행하는 것이 가장 쉽지만 Visual Studio는 약간 더 "마법사"메커니즘을 제공합니다. 구현은 다른 컴파일러에서 가장 다를 가능성이 높습니다.


기본 RC 스크립트를 직접 조작하려면 :

.1. "2 TextinClude"섹션에는 라이브러리의 리소스 ID를 정의하는 헤더 파일이 포함되어 있습니다. 구문은입니다

2 TEXTINCLUDE 
BEGIN
    "#include ""my_first_lib_header.h""\r\n"
    "#include ""my_second_lib_header.h""\0" 
END

.2. "3 TextInclude"섹션에는 라이브러리의 RC 스크립트를 포함하십시오.

3 TEXTINCLUDE
BEGIN
    "#include ""my_first_library.rc""\r\n"
    "#include ""my_second_library.rc""\0"
END

3 단계와 4 단계는 자동으로 발생하지만 Microsoft의 리소스 스크립트 컴파일러에 의존하기보다는 직접 입력하는 것이 더 신뢰할 수 있음을 알았습니다.

.삼. 라이브러리 자원이 읽기 전용 기호 목록에 정의 된 헤더 파일을 추가하십시오. 이 목록은 일반적으로 파일 상단 근처에 있습니다.

#define APSTUDIO_READONLY_SYMBOLS
#include "my_first_lib_header.h"
#include "my_second_lib_header.h"
#undef APSTUDIO_READONLY_SYMBOLS

.4. Apstudio_invoked 섹션에 라이브러리의 RC 스크립트를 포함시킵니다. 이것은 일반적으로 파일의 맨 아래에 있습니다.

#ifndef APSTUDIO_INVOKED
#include "my_first_library.rc"
#include "my_second_library.rc"
#endif 

Visual Studio IDE를 통해이 모든 것을 자동으로 수행 할 수 있지만 예상 할 때 항상 적용되지는 않았습니다.

  1. Visual Studio에서 "Resource View"창을 엽니 다.
  2. 기본 응용 프로그램의 리소스 파일을 마우스 오른쪽 버튼으로 클릭하고 문맥 메뉴에서 "리소스 포함 ..."를 선택하십시오.
  3. "읽기 전용 기호 지시문"으로 표시된 상자에서 라이브러리의 리소스 ID를 정의하는 .h 파일에 대한 포함 명령문을 추가하십시오.
  4. "Compile-Time Directrives"라는 상자에 라이브러리의 .rc 스크립트에 대한 포함 명령문을 추가하십시오.
  5. 괜찮아요. RC 스크립트 컴파일을 수동으로 트리거하여 발생하는지 확인할 수도 있습니다.

라이브러리의 리소스 스크립트가 디스크의 모든 파일 (텍스트 파일, 아이콘 파일 등)을 참조하는 경우 기본 응용 프로그램 프로젝트가 어디에서 찾을 수 있는지 알고 있어야합니다. 이 파일을 애플리케이션에서 찾을 수있는 어딘가에 복사하거나 컴파일러 설정에 추가 포함 경로를 추가 할 수 있습니다.

추가 경로를 추가하려면 :

  1. 기본 응용 프로그램의 속성 대화 상자를 엽니 다.
  2. 왼쪽 탐색 창에서 "구성 속성/리소스/일반"을 선택하십시오.
  3. 속성 목록에 "추가 포함 디렉토리"옆에 관련 경로를 입력하십시오.

나는 그렇게 생각하지 않습니다. 정적 라이브러리에는 자체 역할이 없습니다. 코드는 DLL 또는 EXE의 맥락에서 실행되는 코드입니다. 그렇기 때문에 정적 라이브러리의 코드에서로드하려는 모든 리소스는 DLL/EXE를 둘러싼 것입니다.

그래도 자체 주소 공간이있는 한 DLL과 같은 종류의 리소스 재사용을 수행했으며 DLL의 Hinstance로 LoadResource를 호출 할 수 있습니다.

Visual Studio 2010에 따르면 Microsoft의 개발 도구는 정적 라이브러리 내에서 컴파일된 리소스 데이터를 전혀 제대로 처리할 수 없는 것 같습니다.

컴파일된 리소스 파일(a .res 파일)에는 두 가지 선택 사항이 있습니다.

  1. 배포하다 .res 파일을 별도로 저장하고 클라이언트 코드에 파일을 연결하도록 지시합니다.
  2. 사용 cvtres 여러 개를 병합하려면 .res 파일을 단일 개체(.obj) 파일을 작성하여 별도로 제공하세요.

다음으로 생성된 객체 파일에서는 lib를 실행할 수 없습니다. cvtres.여러 개의 객체 파일이 제공되는 경우 lib 마치 여러 사람인 것처럼 불평한다. .res 파일이 제공되었습니다.단일 객체 파일이 제공되는 경우 lib 불평하지 않지만 링커는 lib 파일에 포함된 리소스 데이터를 무시합니다.

리소스 데이터가 실제로 라이브러리에서 사용 가능하기 때문에(일부 명령줄 옵션, 섹션 조작 등을 사용하여) 링커가 리소스 데이터의 libbed를 읽고 연결하도록 강제하는 방법이 있을 수 있습니다. dumpbin 드러낸다).지금까지 나는 해결책을 찾지 못했고 누군가 개발 도구를 해킹하려는 의지가 없다면 이 간단한 해결책보다 더 나은 것은 아마도 노력할 가치가 없을 것입니다.

정적 라이브러리에 리소스 데이터를 전달하는 유일한 방법(이 경우 ~와 함께 정적 라이브러리)는 리소스를 별도로 배포하고 클라이언트 코드에서 명시적으로 연결하는 것입니다.사용 cvtres 분산된 리소스 파일이 많으면 하나로 줄일 수 있습니다.

권장되는 방법은 라이브러리와 함께 리소스를 DLL에 제공하는 것입니다.

다음 방법을 사용하는 경우 모든 리소스 (이 예에서 아이콘)는 정적 라이브러리의 필수 부분으로 사용할 수 있으며 이러한 라이브러리는 콘솔을 포함하여 모든 유형의 애플리케이션에서 사용할 수 있습니다 ( 모든 리소스 세그먼트).

  1. 아이콘은 정적 바이트 배열로 변환됩니다. BIN2C 그것에 사용될 수 있습니다.
  2. 데이터는 히콘 핸들로 변환됩니다. 내가 한 방법은 다음과 같습니다.

    HICON GetIcon()
    { 
       DWORD dwTmp;
       int offset;
       HANDLE hFile;
       HICON hIcon = NULL;
       offset = LookupIconIdFromDirectoryEx(s_byIconData, TRUE, 0, 0, LR_DEFAULTCOLOR);
       if (offset != 0)
       {
          hIcon = CreateIconFromResourceEx(s_byIconData + offset, 0, TRUE, 0x00030000, 0, 0, LR_DEFAULTCOLOR | LR_DEFAULTSIZE);
       }
       return hIcon;  
    }
    
  3. geticon은 로디콘 대신 사용됩니다. 전화하는 대신 :

m_hIcon = ::LoadIcon(hInstanceIcon, MAKEINTRESOURCE(pXMB->nIcon));

그런 다음 전화하십시오

m_hIcon = GetIcon()
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top