我在使用dynamic
关键字从C#调用COM TLB方法时遇到了一些性能问题(更多信息请参考此处)。由于我没有尝试优化这样的调用,所以现在我正在寻找一种将我的TLB库转换为本地包装DLL的方法,以便在我的C#项目中直接使用它(在此阶段,我甚至不确定这是否有帮助,但是可以将性能问题抽象成下一层)。
我使用tlbimp.exe
从我的COM.tlb文件(已注册)创建了一个.dll,使用VS2013命令提示符和以下命令:
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
注册这个 .dll 文件。
regasm F:\SomeDir\GrpSvr.dll
现在,我将这个.dll文件的引用包含在我的项目中,并尝试通过以下方式实例化GrpCallClass
类:
private GRPSVR.GrpCallClass grpSvr = new GRPSVR.GrpCallClass();
但是这样会产生编译时错误:
Interop 类型 '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 吗?
感谢您的时间。