【问题标题】:Differences in OCX and DLL exception handling?OCX 和 DLL 异常处理的区别?
【发布时间】:2011-01-07 18:49:02
【问题描述】:

我知道 (vc++) ocx 是 ActiveX 控件,而 (vc++) dll 是函数的集合。我发现从 vb.net 应用程序调用时,如果异常是从 ocx 内部或来自 dll 的函数内部抛出的,则捕获某些异常的行为可能会有所不同。

所以我的问题是: 从 VB.net 应用程序的角度来看,使用 .ocx 文件和使用 .dll 文件的主要区别是什么?

【问题讨论】:

    标签: .net dll exception-handling visual-c++ ocx


    【解决方案1】:

    .ocx 包含遵循 OLE 自动化协定的 COM coclass。该合约有一个明确定义的方式来向客户返回错误。每个方法都返回一个 HRESULT,一个指示方法是否成功的代码。它是一个简单的整数,错误代码在 WinError.h SDK 头文件中定义。它还支持通过 IErrorInfo 接口获取有关错误的上下文信息。 CLR 中的 COM 互操作支持确保将失败代码转换为可比较的异常。

    对于 C/C++ DLL 中的代码,不存在这样的标准。如果它完全抛出异常,它几乎总是像 AccessViolation 这样令人讨厌的东西。 P/Invoke marshaller 确保这些异常被捕获和翻译。除了“它不起作用”之外,您总是会从这样的异常中获得很少的有用信息。您应该让这些异常终止您的程序,您无法从中进行有意义的恢复。

    【讨论】:

    • +1 这是最好的解释恕我直言。尽管 C/C++ DLL 仍然可以是 COM DLL,但问题并不完全清楚
    【解决方案2】:

    DLL 是一个共享库。它是一个操作系统级别的对象 - 任何进程都可以加载一个 DLL 并调用其中定义的函数。

    ActiveX 控件是实现特定接口的 COM 对象,允许主机调用其方法并将其嵌入到其 UI 中。 ActiveX 控件必须实现哪些接口才能成功嵌入应用程序的 UI 中存在某些最低要求。由于 COM 对象通常由进程动态加载,因此它们被实现为 DLL。一个 DLL 可以实现一个或多个 COM 类。

    关于异常 - 我不确定您观察到哪些差异,但函数与在您的进程的主 .EXE 文件中实现的函数没有什么不同。抛出的异常应该根据您的编程语言运行时环境定义的规则正常传播。

    ActiveX 方法不同。通常,它是通过称为 IDispatch 接口的东西调用的。它不是一个简单的子例程调用,而是通过调用 IDispatch 接口 (IDispatch::Invoke) 中的方法来调用的,其参数以特定方式编组(本质上,它们被转换为标准类型并以隐藏的方式打包)主进程的实现语言和 ActiveX 控件的实现语言之间调用约定和数据类型的差异。) IDispatch::Invoke 接口然后确定调用者试图访问 ActiveX 中的哪个方法,并直接路由它。

    异常通常不通过 IDispatch 接口传播。您的运行时环境如何处理 IDispatch::Invoke 返回的错误代码实际上由实施者决定。因此,您可以合理地期望在处理 ActiveX 控件中引发的运行时错误和异常时不会满足您的期望。

    【讨论】:

    • 我已经将此答案设置为正确,根据以下内容: * 我的经验是 .DLL 异常以正常方式被捕获,但 .OCX 异常没有被捕获。 * 我尝试过使用 try...catch 块、Application.ThreadException 处理程序、AppDomain.CurrentDomain.UnhandledException 处理程序并将每个值放入 Application.SetUnhandledExceptionMode,所以我认为 OCX 异常没有通过 IDispatch 接口传播。跨度>
    【解决方案3】:

    没有区别。它们都是dll。您可以将 dll 重命名为任何内容,并且仍然可以使用 LoadLibrary、GetProcAddress 加载和使用它。

    【讨论】:

    • 虽然技术上是正确的,但(OCX 是一个 DLL)这不是一个非常有用的答案。 ActiveX 控件通过 IDispatch 接口公开其接口,您无法通过 GetProcAddress() 访问该接口。反正不是直接的。
    【解决方案4】:

    在 .net 世界中,dll 不是函数的集合。它是一个程序集,是 types 的集合——类和模块。这些类型可能还包含函数,但这是不同的抽象级别。

    但是由于您是在与 ocx 文件一起讨论这个问题时,我承认您可能指的是由 vb6 创建的 dll,因为 .Net 与 ocx 文件或 activex 控件没有任何关系。 .在这种情况下,它们都是可以加载的 COM 对象。

    【讨论】:

    • DLL 不是 COM 对象。它可能实现一个 COM 对象,或几个 COM 对象,或者没有。
    • 理所当然,但由 vb6 创建并与 ocx 一起使用的 dll 几乎总是如此。
    • 问题现在已被编辑并说它们是 VC++ DLL,所以它们可能是 COM DLL 或普通的旧 DLL。看起来它们仍然很可能是 COM DLL,因为它们与 VC++ OCX 是同时被提及的
    猜你喜欢
    • 1970-01-01
    • 2014-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-07
    • 2011-11-20
    • 1970-01-01
    相关资源
    最近更新 更多