gpt4 book ai didi

.net - 为什么在不通过 Interop 类的情况下从 .NET 访问 COM 对象有时会起作用?

转载 作者:行者123 更新时间:2023-12-04 02:26:55 24 4
gpt4 key购买 nike

当您从 .NET 代码连接 COM 对象时,VS 会创建一个带有互操作类的互操作 DLL。

例子:

您有一个 foo.dll 实现了一个 COM 库 Foo,其中包括 COM 接口(interface)“IBar”的实现。您将对 foo.dll 的引用添加到 .NET 项目。在/bin 中,您会看到一个 Interop.FooLib.dll。在对象浏览器中,您将看到 Interop.FooLib,在其下方您将看到 FooLib,在其下方您将看到 BarClass,在其下方您将看到 Base Types,在该 Bar 和 IBar 下方。

在您的 .NET 代码中,当声明一个变量时,您可以键入 FooLib,智能感知将为您提供 Bar 或 BarClass() 的选项。

据我了解,在变量声明中使用哪个并不重要,但对于它的构造函数使用哪个非常重要。

也就是说,这两个都应该工作:

FooLib.BarClass theBar = new FooLib.BarClass();
FooLib.Bar theBar = new FooLib.BarClass();

但这不应该工作:
FooLib.Bar theBar = new FooLib.Bar();

这就是问题所在。我们刚刚发现了一个奇怪的错误,其中为某些客户工作并在我们的开发和测试环境中工作的代码在一个客户站点上不起作用,结果证明是使用 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;
};
// ...
};

实现:
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()

// ...
};

-- 稍后添加 --

反编译*,通过 .NET Reflector:
[ComImport, CoClass(typeof(BarClass)), Guid("...")]
public interface Bar : IBar
{
}

*我不在乎 Reflector UI 称之为反汇编 - 如果它输出 HLL,它就是反编译。

最佳答案

好问题。许多人对此感到惊讶,因为 Bar 是一个接口(interface),当然您不应该能够创建接口(interface)的新实例!但是,尽管我似乎找不到任何实现细节,但我记得在 Adam Nathan 的 COM 互操作书中读到 C# 对标有 CoClassAttribute 的 COM 接口(interface)做了一个特殊异常(exception),并将调用转换为 coclass 的实例化。

但我不知道为什么它有时会起作用,有时会不起作用。

关于.net - 为什么在不通过 Interop 类的情况下从 .NET 访问 COM 对象有时会起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3062960/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com