RSS


[ Pobierz całość w formacie PDF ]
.You can also update your component, and your users can begin using theupdated version without breaking their existing software.Traditional Win32 DLLs, by themselves, do not enable component-based software.The limitations ofusing DLLs to build software components includeThe requirement to export your DLL functions by nameIncompatibilities of C++ function decoratingHard-coded DLL names in application EXE filesBuild-time dependencies between DLLs and EXEs DLL Functions Must Be Exported by NameI noted previously today that Microsoft wants functions exported from DLLs by their name, not by anordinal value.When an application uses a DLL, the application must use absolutely unique names toidentify the DLL function(s) it wants to call.If you are going to distribute your DLL for use in other systems (systems with which you areunfamiliar), you need to make sure the function names in your DLL don't duplicate any functionnames from other DLLs that the system might use.With traditional DLLs, there is no easy way to dothat.Your DLL could contain a function that has the same name as a function in another DLL.Incompatible C++ Function Name DecoratingThe need to export your DLL functions by name also causes a problem with C++ function decorating.(Function decorating is also called function name mangling, but decorating is a nicer word.)As you know, C++ functions can be overloaded.Overloaded functions are functions that have thesame name and differ only in their parameter list.The compiler and linker, however, must give eachfunction a unique symbol name.Visual C++ gives each function a unique symbol name by decorating the function's name withadditional alphanumeric characters based on the function's parameters.These alphanumeric charactersare derived from the function parameters and their types and enable the compiler and linker todifferentiate between the overloaded functions.With Visual C++ name decorating, the functionvoid Foo(int i)becomes?Foo@@YAXH@ZYou can witness C++ function name decorating in the following example.Open your ADOMFC1project.Click the File View tab and add a header file called DbComponent.h.Put the code shown inListing 9.1 in DbComponent.h.Listing 9.1.The DbComponent Class Declaration 1: class DbComponent2: {3: public:4: DbComponent();5: int BeepIfDbIsOk();6: };Next, include the DbComponent.h file in the CADOMFC1Doc.cpp file, like this:#include "DbComponent.h"Then add the code in Listing 9.2 to the CADOMFC1Doc::OnNewDocument function.(You should,of course, leave the existing code in OnNewDocument and merely add this code to it, perhaps nearthe beginning of the function.)Listing 9.2.Calling the DbComponent BeepIfDbIsOk Function1: DbComponent * pDb = new DbComponent();2: pDb->BeepIfDbIsOk();3: delete pDb;Now try to build the ADOMFC1 application.You should receive two linker errors for unresolvedexternal symbols.You will notice that one symbol, which corresponds to the BeepIfDbIsOkfunction, looks like this:?BeepIfDbIsOk@DbComponent@@QAEHXZThe other symbol, which corresponds to the constructor for DbComponent class, looks like this:??0DbComponent@@QAE@XZYou are seeing C++ function name decorating in action.When the Visual C++ compiler buildsADOMFC1Doc.obj, it decorates the names of the DbComponent constructor and the BeepIfDbIsOk function.The linker then tries to find the code for those functions, but it cannot, andit generates the unresolved external symbol errors.If a DLL existed with the DbComponent code in it, the DbComponent constructor and theBeepIfDbIsOk function would need to exist in the DLL with the decorated names that the VisualC++ linker expects.Otherwise, the linker would not find them and would still generate unresolvedexternal symbol errors.Unfortunately, function decorating is not uniform among C++ compilers.C++ functions exportedfrom a DLL built with Visual C++ cannot be called in an application built with Borland C++.AVisual C++ DLL and a Borland C++ EXE are incompatible, at least in terms of C++ function calls.NOTEYou can disable C++ name decorating for functions that you export from aDLL, by placing the DLL within external "C" { } blocks.This causesthe exported functions to have the signature of a standard C languagefunction.This will enable your DLL functions to be called from EXEs builtwith other compilers but will cost you the C++ features and the object-oriented nature of your component.Therefore, if you put your C++ component in a traditional Win32 DLL, it can be used only in softwarebuilt with the same compiler that you used.Hard-Coded DLL NamesWhether an application uses implicit load-time linking or explicit runtime linking to call functions in aDLL, the DLL's name is hard-coded into the application's EXE file.This results in a few limitationsfrom a component software standpoint.The DLL file must exist somewhere that the OS can find it.One place is the application directory.However, if the DLL file existed in the application directory, no other application on the machinewould be able to find it.Another place to put the DLL might be the Windows System directory.If the DLL exists in theWindows System directory, it runs the risk of being overwritten by, or at least conflicting with,another DLL that happens to have the same name.A true software component needs to be safely installable on any machine and accessible to all theappropriate applications on that machine.Hard-coded DLL names in the application EXE files aredetrimental to this.Build-Time Dependencies Between the DLL and the EXEs That Use it The most common way for applications to use a DLL is to link with its import library (implicit load-time linking).The other method-explicit runtime linking with the LoadLibrary andGetProcAddress functions-is not used nearly as often.Using LoadLibrary andGetProcAddress isn't as convenient for the application developer as simply linking to the DLL'simport library and having the OS automatically load the DLL.However, a problem occurs when it comes time to update the DLL.A true software component can beupdated independently of the rest of the system.In other words, you can install and use a new versionof a component without breaking the existing system.With traditional Win32 DLLs, when you modify the code and rebuild the DLL, the information in theimport library can change.You will recall that the import library contains the function names exportedfrom the DLL.The import library also contains import records for those functions that are fixed upwhen the DLL is loaded and the addresses are known.This means that when a DLL is updated, the applications that use the DLL (by linking with the DLL'simport library) need to be rebuilt also to ensure that the system is stable.Therefore, a build-timedependency exists between the application EXE and the DLLs that it uses.NOTEIt might be possible to update a DLL without updating the EXEs that use it,if you don't change any existing functions in the DLL.However, there is nomechanism for the EXE to gracefully recover if the DLL does become outof sync.Also, replacing an existing DLL with an older version quite oftencauses problems that the application cannot deal with gracefully.The easewith which this problem can occur and the lack of mechanisms to enable agrace-ful recovery at runtime mean that, for most practical purposes, there isa build-time dependency between an EXE and the DLLs it uses.With traditional Win32 DLLs, you cannot simply plug a new version of the DLL into an existingsystem without the risk of breaking it.If you place a new DLL in an existing system withoutrebuilding the applications that use the DLL, the applications could crash because of changes in thefunctions in the DLL [ Pobierz całość w formacie PDF ]
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • wblaskucienia.xlx.pl