Debug DLL에서 잘 가져 오지 않은 간접 typelib
-
02-07-2019 - |
문제
VC2005를 사용하여 건축 할 3 가지 프로젝트가 있습니다.
- liba (typelib 포함, liba.dll in liba.dll) : IDL은 줄이 있습니다.
library libA { ...
- libb (liba를 가져 오기, libb.dll in libb.dll) : IDL은 줄이 있습니다.
importlib( "libA " );
- libc (imports libb) : 소스 파일 중 하나에 포함
#import <libB.dll>
그만큼 #import <libB.dll>
다음과 같은 방식으로 컴파일러에 의해 처리됩니다 (문서에 따라) :
- %경로 %의 검색 디렉토리
- %lib %의 검색 디렉토리
- "추가 포함 경로"(/I 컴파일러 옵션) 검색
LIBC를 컴파일 할 때 Cl.exe가 실행 가능한 경로에서 liba.dll을 명확하게 찾을 수 있음을 알 수 있습니다 (filemon.exe 사용)
VC 오류 C4772 : #다른 종속성을 가진 typelib의 #
그러나 여전히 Liba 네임 스페이스는입니다 ~ 아니다 발견되고 Liba 유형에 대한 모든 참조는 다음으로 대체됩니다. __missing_type__
(편집) 한편, 디버그 DLL을 사용할 때만 문제가 나타납니다.
전에이 문제를 본 사람이 있습니까? 그리고 그것을 해결 했습니까?
해결책 4
마침내 그것을 찾았습니다!
Visual Studio 프로젝트에서 Liba의 A.Idl 파일에는 mktypelib 호환 설정. 이것은 A 프로젝트에서 상속 된 행동을 무시했습니다. 상황을 악화시키기 위해 디버그 구성에만 있었다.
결과는 모든 것에 대한 것이 었습니다
typedef [public] tagE enum { cE1, cE2 } eE;
결과가 발생했습니다 tagE
결과 Typelib에서 정의되지 않습니다. Libb가 그랬을 때 import( "A.dll" )
, 모든 참조 tagE
대체되었습니다 __missing_type__
...
다른 팁
프로젝트의 종속성을 명시 적으로 설정하고 있습니까? 다시 말해 프로젝트 C가 프로젝트 B에 의존하고 프로젝트 B가 프로젝트 A에 의존하도록 IDE에서 솔루션을 설정 했습니까?
libc에서 liba에 정의 된 유형을 사용하고 있습니까? 그렇다면 Liba의 유형에 대해 알 수 있도록 Libc에서 Liba를 직접 가져와야한다고 생각합니다. com은 다른 유형 라이브러리에서 자체적으로 참조 된 유형 라이브러리를 자동으로 참조하지 않습니다.
나는 당신에게 답이 없지만, 나는이 경험을 여러 번 가지고 있었고 내가 한 일을 공유하고 싶습니다.
몇 가지 관련이없는 프로젝트에서 동일한 시나리오가있었습니다. 나는 거의 일주일 동안 의존성을 해결하기 위해 거의 일주일 동안 시도했지만 결국 일정을 유지하기 위해 손실을 줄여야했습니다. .tlh 파일에서 #include를 사용하여 (dll에서 가져 오는 것은 이들을 생성 할 것입니다), "classic com"API 호출을 사용하여 .tlh 파일 내의 구조에 포인터를 가져옵니다. 코드는 래퍼 파일을 사용할 수있는 경우와 마찬가지로 작업하기에 깨끗하지는 않지만 작동합니다.
IUnknown *lpUnk;
hr = CoCreateInstance(clsID, NULL, CLSCTX_LOCAL_SERVER, IID_IUnknown, (void **)&lpUnk);
if (FAILED(hr)) throw SomeException;
//
_Application *app; //Address _Application
hr = lpUnk->QueryInterface(__uuidof(_Application), (void **) &app);
lpUnk->Release();
if (FAILED(hr)) throw SomeException;
// Do stuff with the app object
app->Release(); // Then release
CComPTR 래퍼 템플릿을 사용하여 범위를 벗어날 때 파괴자와 함께 릴리스를 안정적으로 수행 하여이 문제를 "이민화"할 수 있습니다.
CComPtr<IUnknown> lpUnk;
hr = CoCreateInstance(clsID, NULL, CLSCTX_LOCAL_SERVER, IID_IUnknown, (void **)lpUnk);
if (FAILED(hr)) throw SomeException;
//
CComPtr<_Application> app; //Address _Application
hr = lpUnk->QueryInterface(__uuidof(_Application), (void **) &app);
if (FAILED(hr)) throw SomeException;
//
// Do stuff with the app object
_application 포인터는 .tlh 파일의 구조 중 하나를 사용하는 예입니다.