不能从调试 dll 很好地导入间接 Typelib
Posted
技术标签:
【中文标题】不能从调试 dll 很好地导入间接 Typelib【英文标题】:Indirect Typelib not imported well from Debug dll 【发布时间】:2008-09-26 14:03:54 【问题描述】:使用 VC2005,我有 3 个项目要构建:
libA(包含一个typelib,产生libA.dll):IDL有一行library libA ...
libB(包含导入libA的typelib,导致libB.dll):IDL有一行importlib( "libA " );
libC(导入 libB):其中一个源文件包含 #import <libB.dll>
#import <libB.dll>
由编译器按以下方式处理(根据文档):
-
搜索 %PATH% 的目录
搜索 %LIB% 的目录
搜索“其他包含路径”(/I 编译器选项)
在编译libC的时候,我可以看到cl.exe清晰的可以找到可执行路径下的libA.dll(使用Filemon.exe)
VC 错误 C4772:#import of typelib 与另一个依赖项
但是,仍然找不到 libA 命名空间,并且所有对 libA 类型的引用都替换为 __missing_type__
(edit) 同时,我发现这个问题只在使用调试 dll 时出现。
以前有人见过这个问题吗?并解决了吗?
【问题讨论】:
【参考方案1】:您是否明确设置了项目的依赖项?换句话说,您是否在 IDE 中设置了解决方案,使项目 C 依赖于项目 B,而项目 B 依赖于项目 A?
【讨论】:
最初,我有一个包含所有三个项目以及依赖项的解决方案。这没有用。现在我正在使用这三个项目文件,使用 devenv.com 命令以正确的顺序一一构建它们。【参考方案2】:您是否使用 libC 中的 libA 中定义的类型?如果是这样,我认为您需要直接从 libC 导入 libA,以便它知道 libA 的类型。 COM 不会自动引用其他类型库引用的类型库。
【讨论】:
【参考方案3】:我没有给你答案,但我有过几次这样的经历,我想分享一下我的所作所为。
在几个不相关的项目中,我遇到了与您相同的情况。在一个案例中,我尝试了将近一周的时间来解决依赖关系,但最终我不得不减少损失以保持进度。我最终在 .tlh 文件上使用了 #include(在 DLL 上执行导入将生成这些),然后使用“经典 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 文件中的结构之一的示例。
【讨论】:
感谢您的提示,但我会通过这个...因为#importing 发布 dll 工作正常(即使是调试版本)。【参考方案4】:终于找到了!
在 Visual Studio 项目中,LibA 中的 A.idl 文件将 MkTypeLib Compatible 设置为 ON。这推翻了从 A 项目继承的行为。更糟糕的是,它仅在 Debug 配置中为 ON。
结果是每个
typedef [public] tagE enum cE1, cE2 eE;
这导致tagE
未在生成的类型库中定义。当 LibB 使用 import( "A.dll" )
时,所有对 tagE
的引用都被替换为 __missing_type__
...
【讨论】:
以上是关于不能从调试 dll 很好地导入间接 Typelib的主要内容,如果未能解决你的问题,请参考以下文章
Window 7 上的 ATL COM DLL 注册无法更新 CLSID 部分,但 TypeLib 可以工作
(lat, lon) WKT 坐标不能用 st_transform 很好地重新投影