我知道 (vc++) ocx 是 ActiveX 控件,而 (vc++) dll 是函数的集合。我发现从 vb.net 应用程序调用时,如果异常是从 ocx 内部或来自 dll 的函数内部抛出的,则捕获某些异常的行为可能会有所不同。
所以我的问题是:从 VB.net 应用程序的角度来看,使用 .ocx 文件和使用 .dll 文件之间的主要区别是什么?
我知道 (vc++) ocx 是 ActiveX 控件,而 (vc++) dll 是函数的集合。我发现从 vb.net 应用程序调用时,如果异常是从 ocx 内部或来自 dll 的函数内部抛出的,则捕获某些异常的行为可能会有所不同。
所以我的问题是:从 VB.net 应用程序的角度来看,使用 .ocx 文件和使用 .dll 文件之间的主要区别是什么?
.ocx 包含遵循 OLE 自动化协定的 COM coclass。该合约有一个明确定义的方式来向客户返回错误。每个方法都返回一个 HRESULT,一个指示方法是否成功的代码。它是一个简单的整数,错误代码在 WinError.h SDK 头文件中定义。它还支持通过 IErrorInfo 接口获取有关错误的上下文信息。CLR 中的 COM 互操作支持确保将失败代码转换为可比较的异常。
C/C++ DLL 中的代码不存在这样的标准。如果它完全抛出异常,它几乎总是像 AccessViolation 这样令人讨厌的东西。P/Invoke marshaller 确保这些异常被捕获和翻译。除了“它不起作用”之外,您总是会从这样的异常中获得很少的有用信息。您应该让这些异常终止您的程序,您无法从中进行有意义的恢复。
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。您可以将 dll 重命名为任何内容,并且仍然可以使用 LoadLibrary、GetProcAddress 加载和使用它。
在 .net 世界中,dll 不是函数的集合。它是一个程序集,它是类型的集合——类和模块。这些类型可能还包含函数,但这是不同的抽象级别。
但是由于您是在与 ocx 文件一起讨论这个问题时,我承认您可能指的是由 vb6 创建的 dll,因为 .Net 与 ocx 文件或 activex 控件没有任何直接关系。在这种情况下,它们都只是您可以加载的 COM 对象。