当您从.NET代码接口COM对象时,VS会创建一个带有互操作类的互操作DLL.
例:
你有一个foo.dll实现了一个COM库Foo,它包含了一个COM接口"IBar"的实现.您将foo.dll的引用添加到.NET项目.在/ bin中,您将看到一个Interop.FooLib.dll.在对象浏览器中,您将看到Interop.FooLib,在其下您将看到FooLib,您将看到BarClass,您将在该Bar和IBar下看到Base Types.
在.NET代码中,当声明变量时,可以键入FooLib,而intellisense将为您提供Bar或BarClass()的选项.
根据我的理解,你在变量声明中使用它并不重要,但是它对于它的构造函数非常重要.
也就是说,这两个都应该有效:
FooLib.BarClass theBar = new FooLib.BarClass();
FooLib.Bar theBar = new FooLib.BarClass();
Run Code Online (Sandbox Code Playgroud)
但这不应该奏效:
FooLib.Bar theBar = new FooLib.Bar();
Run Code Online (Sandbox Code Playgroud)
这是问题所在.我们刚刚找到了一个奇怪的错误,其中代码适用于某些客户,并且在我们的开发和测试环境中工作,但是在一个客户站点上工作,结果是使用Bar()构造函数的程序员.
那么,任何人都可以准确地解释两个构造函数Bar()和BarClass()之间的区别吗?
任何人都可以解释为什么Bar()构造函数似乎有效吗?
任何人都可以提供一种方法来确保没有人错误地调用错误的构造函数,而不读取每行代码吗?
- 添加 -
有人提出问题出在我们的COM实施中.这就是我们正在做的事情:
IDL:
[
object,
uuid(...),
dual,
helpstring("IBar Interface"),
pointer_default(unique),
nonextensible
]
interface IBar : IDispatch
{
[id(1), helpstring("method barify")]
HRESULT barify([out, retval] VARIANT_BOOL *rVal);
// ...
};
// ...
[
uuid(...),
version(1.0),
helpstring("Foo 1.0 Type Library")
]
library FooLib
{
importlib("stdole32.tlb");
importlib("stdole2.tlb");
// ...
[
uuid(...),
helpstring("Bar Class")
]
coclass Bar
{
[default] interface IBar;
};
// ...
};
Run Code Online (Sandbox Code Playgroud)
实施:
class ATL_NO_VTABLE CBar :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CBar, &CLSID_Bar>,
public IDispatchImpl<IBar, &IID_IBar, &LIBID_FooLib>,
public ISupportErrorInfoImpl <&IID_IBar>
{
public:
CBar();
DECLARE_REGISTRY_RESOURCEID(IDR_BAR)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CBar)
COM_INTERFACE_ENTRY(IBar)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(ISupportErrorInfo)
END_COM_MAP()
// ...
};
Run Code Online (Sandbox Code Playgroud)
- 稍后添加 -
通过.NET Reflector反编译*:
[ComImport, CoClass(typeof(BarClass)), Guid("...")]
public interface Bar : IBar
{
}
Run Code Online (Sandbox Code Playgroud)
*我不关心Reflector UI将其称为反汇编 - 如果它输出HLL,则它是反编译.
很好的问题。许多人对此感到惊讶,因为 Bar 是一个接口,并且您当然不应该能够创建接口的新实例!但是,尽管我似乎找不到任何实现的细节,但我记得在 Adam Nathan 的 COM 互操作书中读到,C# 对标有 CoClassAttribute 的 COM 接口做了一个特殊的例外,并将调用转变为 coclass 的实例化。
但不知道为什么有时有效有时无效。
| 归档时间: |
|
| 查看次数: |
461 次 |
| 最近记录: |