I know a (vc++) ocx is an ActiveX control, and a (vc++) dll is a collection of functions. I've found that being called from a vb.net application, the catching of some exceptions could behave differently if the exception is being thrown from inside the ocx 开发者_如何转开发or inside a function that comes in a dll.
So my question is: From a point of view of a VB.net application, what are the main differences between using .ocx files and using .dll files?
A DLL is a shared library. It's an OS level object - any process can load a DLL and call functions defined in it.
An ActiveX control is a COM object that implements specific interfaces that allows hosts to call its methods and embed it in their UI. There are certain minimum requirements on which interfaces an ActiveX control must implement to be embedded successfully in an application's UI. Since COM objects are typically dynamically loaded by a process, they are implemented as a DLL. A single DLL may implement one COM class or more.
Regarding exceptions - I'm not sure what differences you've observed, but a function is no different from a function implemented in your process's main .EXE file. An exception thrown in it should propagate normally according to the rules defined by your programming language's runtime environment.
An ActiveX method is different. Typically, it's called through something called an IDispatch interface. Rather than being a simple subroutine call, it's invoked by calling a method in the IDispatch interface (IDispatch::Invoke), with its arguments marshaled in a specific way (essentially, they're converted to standard types and packaged in a way that hides differences in calling conventions and data types between the implementation language of the main process and that of the ActiveX control.) IDispatch::Invoke interface then determines which method in the ActiveX the caller is trying to access, and routes it directly.
Exceptions are generally not propagated through the IDispatch interface. How your runtime environment deals with the error codes returned by IDispatch::Invoke is up to the implementer to decide, really. So you can reasonably expect not to have your expectations met when dealing with runtime errors and exceptions thrown in an ActiveX control.
An .ocx contains COM coclasses that follow the OLE automation contract. That contract has a well defined way to return errors to a client. Every method returns an HRESULT, a code that indicates whether the method succeeded or not. It is a simple integer, error codes are defined in the WinError.h SDK header file. It also supports getting context info about the error through the IErrorInfo interface. The COM interop support in the CLR ensures that a failure code is translated into a comparable Exception.
No such standard exists for code in C/C++ DLLs. If it throws an exception at all, it is almost always something nasty like an AccessViolation. The P/Invoke marshaller makes sure these exceptions are caught and translated. You'll invariably get very little useful info out of such an exception beyond "it didn't work". You should let these exceptions terminate your program, you cannot meaningful recover from it.
There is no difference. They are both dlls. You can rename a dll to anything and still load and use it using LoadLibrary, GetProcAddress.
In the .net world, a dll is not a collection of functions. It is an assembly, which is a collection of types — classes and modules. Those types likely also contain functions, but that's a different level of abstraction.
But since you're talking about this in conjunction with ocx files I'll grant that maybe you're referring to a dll created by vb6, since .Net doesn't have anything to do with ocx files or activex controls directly. In that case, they are both just COM objects you can load.
精彩评论