【发布时间】:2014-05-07 20:06:15
【问题描述】:
在使用 dynamic 关键字 (more information here) 从 C# 调用 COM TLB 方法时,我遇到了一些性能问题。因为我在尝试优化此类调用时没有任何运气,我现在正在寻找一种将我的 TLB 库转换为本机包装 DLL 的方法,我可以直接在我的 C# 项目中使用它(在这个阶段我什至不确定这是否会帮助,而是将性能问题抽象到一层)。
我已使用tlbimp.exe 使用 VS2013 命令提示符和命令从我的 COM .tlb 文件(已注册)创建一个 .dll
tlbimp F:\SomeDir\GrpSvr.tlb /out:F\SomeDir\GrpSvr.dll
这产生了一个托管包装 C# .dll,我可以使用 dotPeek 检查它。它包含预期的命名空间
namespace GRPSVR
{
[TypeLibType(TypeLibTypeFlags.FCanCreate)]
[Guid("FFB54BC4-B15E-11D1-99BC-0000E803C444")]
[ClassInterface(ClassInterfaceType.None)]
[ComImport]
public class GrpCallClass : IGrpCall, GrpCall { /*Expected Methods et al.*/ }
}
和两个接口IGrpCall 包含生成类的完整模板和空接口GrpCall。我使用regasm.exe 和
regasm F:\SomeDir\GrpSvr.dll
现在,我在我的项目中包含对这个 .dll 的引用,并尝试通过
实例化GrpCallClass 类
private GRPSVR.GrpCallClass grpSvr = new GRPSVR.GrpCallClass();
但这会给编译时错误:
无法嵌入互操作类型“GRPSVR.GrpCallClass”。请改用适用的接口。
那我试试
private GRPSVR.IGrpCall grpSvr = new GRPSVR.GrpCall();
这在编译时有效,但在运行时我得到一个
附加信息:检索具有 CLSID {FFB54BC4-B15E-11D1-99BC-0000E803C444} 的组件的 COM 类工厂失败,原因是以下错误:80040154 未注册类(来自 HRESULT 的异常:0x80040154 (REGDB_E_CLASSNOTREG))。
但是我已经注册了 .dll。
这种方法是否有助于提高初始 COM TLB 程序集中调用方法的性能?
谁能解释我做错了什么以及如何将我的 COM .tlb 库转换为本机包装器 .dll?
感谢您的宝贵时间。
【问题讨论】:
-
看起来你正朝着正确的方向前进。在注册表中查找您的类并查看它是否存在,就像您查看任何其他 COM 对象一样。此外,请注意许多 COM 组件仅是 32 位的,因此您的调用应用程序也应该是 32 位的。请注意,注册实用程序也有 32 位和 64 位版本。