2009-10-14 3 views
1

다음과 같은 긴 게시물을 보내시면 죄송합니다.내 응용 프로그램이 정적으로 동적으로 연결된 CRT를 어떻게 만드는 지 알 수있는 방법은 무엇입니까?

Microsoft에서 제공하는 정적으로 링크 된 동적으로 링크 된 C 및 C++ 런타임을 혼합하는 것은 좋지 않습니다. 직장에서 우리의 응용 프로그램은 이미 불행히도 그들을 섞어 우리는 그것을 해결하기 위해 노력 해왔다. 여러 가지 이유로 (MSI에 익숙하지 않은 MSI, MSM을 잘 지원하지 않는 NSIS를 사용한다는 사실, 시간과 리소스가 부족함) 우리는 CRT를 동적으로 연결하지 않고 정적으로 연결하기로 결정했습니다. 나는 이것이 왜 좋은 생각이 아닌지에 대한 이유를 안다.하지만 그것은 지금 우리가 선택한 것이었다.


우리 코드는 대부분 다른 많은 오픈 소스 라이브러리에 의해 보완 된 표준 C++입니다.

응용 프로그램의 구조는 다음과 같습니다. 정적 라이브러리가 만들어져 다양한 문제를 일으키는 정적 라이브러리를 만들어내는 다양한 모듈.

릴리스에서 우리는 모두 코드를/MT로 빌드합니다. 일부 오픈 소스 라이브러리의 경우 사전 컴파일 된 바이너리를 사용했으며 그 중 일부는/MD로 미리 컴파일 된 dll 이었기 때문에 런타임을 혼합했습니다. 그래서 우리는/MT를 사용하여 그것들을 다시 컴파일하고 dll이 아닌 정적 라이브러리를 만들어 냈습니다. 이 변환은 각 라이브러리에 대해 수행되지 않으므로/MD를 사용하는 일부 DLL과 여전히 연결됩니다.


결과는 지금 우리 물건 의 Depends.exe를 모두 제외하고는 하나 개의 실행직접가 msvcr80.dll 또는 msvcp80.dll에 의존하지 않는다는 것입니다. 은 직접적으로에 의존하지 않습니다. msvcr80.dll은 depends.exe가 표시하는 트리의 루트 하위가 아닙니다. 때로는 msvcr80.dll이 라이브러리 dll 중 하나에 의해 검색되었지만 트리에서 더 깊은 수준입니다.

그 성가신 실행 파일의 첫 번째 단계에서 msvcr80.dll이 왜 발생하는지 어떻게 알 수 있습니까? 그 실행 파일을 msvcr80.dll에 직접 링크시키는 이유는 무엇입니까?

우리는 CRT와 동적으로 링크되도록/MD를 사용하는 라이브러리 A에 정적으로 링크 할 수있는 한 가지 이유가있을 수 있습니다. 따라서 라이브러리 A의 코드는 실행 파일에서 끝나기 때문에 실행 파일은 msvcr80.dll과 연결됩니다. 그러나 도서관 중 어떤 도서관이 그렇게하는지 어떻게 알 수 있습니까?


는 지금까지 시도하는 것 :

  • 부하 정적 lib 디렉토리 링크 된 파일을 Depends.exe를에 - Depends.exe를가 실행 파일 또는 DLL이 아닌 정적 라이브러리
  • 을 기대하기 때문에>가 작동하지 않습니다
  • 정적으로 링크 된 .lib 파일에 dumpbin.exe/DIRECTIVES를 사용하십시오. - 그 중 아무 것도 msvcrt80.dll을 보여주지 못했습니다 (디버그에서/MDd를 모든 것을 사용하려고 시도 할 때, 그들은 msvcrt80d.dll을 보여주었습니다. 메서드가 좋으며 모든 정적으로 링크 된 오픈 소스 라이브러리가/MT와 함께 올바르게 컴파일되었음을 증명 함)
  • 은/VERBOSE : LIB 링커 플래그를 사용합니다. msvcrt.dll에 대한 가져 오기 라이브러리 인 msvcrt.lib를 실제로 가져 왔음을 보여 주었으므로 문제가 발생하지만 그 이유는 밝히지 않았습니다.
  • Visual Studio에서/VERBOSE 링커 플래그 +를 사용합니다. 추가 종속성 libcmt.lib + 모든 기본 라이브러리 무시 YES + msvcrt를 만들기위한 절박한 시도로 특정 라이브러리 무시 : msvcrt.lib.lib는 사라지거나 누가 그것을 가져 왔는지 보게됩니다. 결과는 난처한 상황에 빠진 날 :
 
    Searching C:\Program Files\Microsoft Visual Studio 8\VC\lib\msvcrt.lib: 
     Found "public: virtual void * __thiscall type_info::`vector deleting destructor'(unsigned int)" ([email protected]@[email protected]) 
     Referenced in libcmt.lib(typinfo.obj) 
     Loaded msvcrt.lib(ti_inst.obj) 
      msvcrt.lib(ti_inst.obj) : error LNK2005: "private: __thiscall type_info::type_info(class type_info const &)" ([email protected]@[email protected]@@Z) already defined in libcmt.lib(typinfo.obj) 
      msvcrt.lib(ti_inst.obj) : error LNK2005: "private: class type_info & __thiscall type_info::operator=(class type_info const &)" ([email protected]@[email protected]@@Z) already defined in libcmt.lib(typinfo.obj) 
     Found "void __stdcall `eh vector destructor iterator'(void *,unsigned int,int,void (__thiscall*)(void *))" ([email protected]@[email protected]) 
     Referenced in msvcrt.lib(ti_inst.obj) 
     Loaded msvcrt.lib(ehvecdtr.obj) 

지금까지 내가 LIBCMT.LIB에 typinfo.obj이 기호를 참조하는 다음 msvcrt.lib에를 검색하고 ti_inst.obj에서 찾은 후이 오류가 발생합니다, 이해하는 그것은 두 번 정의됩니다. 그러나 이것은 이해가되지 않습니다. libcmt.lib에 이미 기호가있는 경우 왜 msvcrt.lib에서 검색하여 결국 실행 파일에 msvcr80.dll을 가져 오나요? 더 일반적으로 정적 라이브러리가 동적 가져 오기 라이브러리의 심볼을 검색하는 이유는 무엇입니까? 특정 라이브러리 무시에서 링커가 msvcrt.lib을 보는 이유는 무엇입니까?

양해 해 주셔서 감사합니다 .--).

답변

3

내 문제에 대한 해결책이 있습니다. 아마 고대부터 거기에 남아있는 어리석은 실수 였을 것입니다.

msvcrt.lib은 추가 종속성 상자에 명시 적으로 언급되어 있습니다 .-(따라서 dll은 종속성을 갖게되었습니다. 그리고 모든 오픈 소스 라이브러리 때문에 상자에 많은 텍스트가 있으므로, 우리가 프로젝트에서 그렇게 큰 실수가있을 수 있다고 생각하지 않았기 때문에 솔직히 말해서 상자를주의 깊게 바라 보는 것조차 생각조차하지 못했습니다.

1

depends.exe로 실행 파일을 열고 built in 된 프로파일 러를 실행하십시오. 나는 이것이 모든 dll이로드되는 이유와로드 된 곳에서 로그 할 것이라고 생각합니다. "LoadLibrary 함수 호출 로그"옵션을 참조하십시오.

+0

제안 해 주셔서 감사합니다. 내 응용 프로그램은 msvcrt80.dll에서 LoadLibrary를 호출 할 것이므로 해당 DLL이 지연되어로드되지만 직접 볼 수 있도록 연결됩니다.로드 된 "MSVCR80.DLL"은 스레드 1에 의해 주소가 0x78130000입니다. 성공적으로 후크 된 모듈 문제가 발생했습니다. 어리석은 실수로 인한 것으로 밝혀졌습니다. 제 대답을보십시오. –

관련 문제