Invoke. This method allows calling methods of a class by name, with an arbitrary number of parameters. Neither the name of the method nor the number (and exact types) of parameters need to be known at compile time, as it is the case for COM objects not supporting Automation; moreover, in scripting languages there is no "compile time" at all. This technique is called late binding.Most existing COM components are Automation-compliant and furthermore allow both late binding and traditional, compile-time early binding. This is achieved by implementing so-called dual interfaces, which are interfaces derived from IDispatch. Generally, both late and early binding expose the same functionality for Automation clients; languages such as Visual Basic and Delphi, as well as some C++ libraries, which provide a higher level of abstraction for COM, make sure that all Automation components created in these languages correctly duplicate their interfaces with late and early binding.
Generally, implementing early binding is more troublesome . Late binding is slower, but more reliable, as it does not require binary compatibility between versions of the same component. For late binding, a client only needs to know the name (or CLSID) of the desired object and the names and parameters of methods it actually uses, while for early binding, the client needs to know the complete definition and identifier (IID) for every interface requested, as well as the exact position of each method in the interface vtable. This is, however, more a problem of COM in general rather than Automation, as early binding relies on traditional COM calling conventions.
Automation servers may be implemented as single-use or multi-use. For the former, each client connects to an individual instance of the server, with an individual instance of its class factory. For the latter, many clients connect to a single server, sharing that server's class factory across all clients.
The servers for the automation objects may be either out-of-process executables or in-process DLLs.
oleview.exe, part of the Microsoft Platform SDK) or the Object Browser in Visual Basic (up to version 6) and Visual Studio .NET.Also, type libraries are used to generate Proxy pattern/stub code for interoperating between COM and other platforms, such as Microsoft .NET and Java. For instance, the .NET Framework SDK includes tools that can generate a proxy .NET DLL to access Automation objects using both early binding (with information about interfaces extracted from a type library) and late binding (via IDispatch, mapped to the .NET Reflection API), with the built-in .NET-to-COM bridge called COM Interop. While Java lacks built-in COM support, toolsets like JACOB and jSegue can generate proxy source code (consisting of two parts, a set of Java classes and a C++ source for a Java Native Interface DLL) from type libraries. These solutions only work on Windows.
Microsoft has publicly documented the object model of all of the applications in Microsoft Office, and some other software developers have also documented the object models of their applications. Object models are presented to automation controllers as type libraries, with their interfaces described in ODL.
use strict;
use warnings; use OLE; # OLE.pm module my $xlfile = "c:workingdirPerltest.xls"; # supply a test xls or csv
my $xl = CreateObject OLE 'Excel.Application' || die $!;
$xl->{'Visible'} = 1;
my $book = $xl->Workbooks->Open($xlfile);
my $sheet = $book->Worksheets(1);
my $a1 = $sheet->Range("A1")->{'Value'};
my $b1 = $sheet->Range("B1")->{'Value'};
my $a2 = $sheet->Range("A2")->{'Value'};
my $b2 = $sheet->Range("B2")->{'Value'};
$xl->ActiveWorkbook->Close(0);
$xl->Quit(); print $a1, " ", $b1, "n"; #1st row
print $a2, " ", $b2, "n"; #2nd row
The following Visual Basic 6 (or VBA) code launches Microsoft Excel, creates a new document, selects some cells, types "Hello World!" into cells A1:C6, and then shows the application window. It operates using late binding, but early binding can be enabled simply by changing the object type from Object (an alias for IDispatch) to Excel.Application, provided that the Excel type library is referenced in the project.
Here is a sample code for C++, which just makes the window visible, using the pure COM API for late binding without other libraries or wrappers:
// Start Excel as a COM server in a separate process
hres = CoCreateInstance(clsid, 0, CLSCTX_LOCAL_SERVER, IID_IDispatch, (void **)&excelApp); if(FAILED(hres))
{
DISPID dispidVisible;
OLECHAR *propertyName = "Visible";
hres = excelApp->GetIDsOfNames(IID_NULL, &propertyName, 1, LOCALE_SYSTEM_DEFAULT, &dispidVisible); if(FAILED(hres))
{
unsigned returnArg;
VARIANT varTrue;
DISPPARAMS params = { &varTrue, 1, 0, 0 }; // set the variant to a boolean true
varTrue.vt = VT_BOOL;
varTrue.boolVal = 0xFFFF; // make the window visible: excelApp.Visible = True
hres = excelApp->Invoke(dispidVisible, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYPUT, params, 0, 0, &returnArg); if(FAILED(hres))
{
// ... use the object // free the object
excelApp->Release();
// error handling
} // error handling
} // error handling
}
Here is an example C++ code (doing the same as the Visual Basic code) using VOLE, a compiler-independent COM/Automation driver library:
object excelApp = object::create("Excel.Application", CLSCTX_LOCAL_SERVER);
object workBooks = excelApp.get_property
Here is an example C++ code (doing the same as the Visual Basic code) using MFC-provided wrappers for Excel 97:
// ... OleVariant covTrue((short)TRUE), covFalse((short)FALSE), covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR); _Application excelApp; if(!excelApp.CreateDispatch("Excel.Application"))
{
excelApp.GetWorkbooks().Add(covOptional);
excelApp.GetRange(COleVariant("A1"),COleVariant("C6")).Select();
excelApp.GetActiveCell().SetFormula("Hello World!");
excelApp.SetVisible(TRUE);
// error handling
}
Finally, here is an example for PHP5:
?>
In C# (and VB.NET with strict type checking) late binding is always explicit, producing code almost as complex as the pure C++ example. In contrast, early binding in .NET offers cleaner-looking code, like the other three examples (although the given examples implicitly involve late binding while .NET does not).