VOLE is an open-source C++ library that dramatically simplifies the business of driving
COM servers (via the IDispatch interface) from C++.
VOLE is highly robust.
VOLE is very flexible, taking and returning normal C++ types,
such as int, double, std::string,
std::wstring, and so on.
VOLE is 100% header only.
VOLE is compiler-independent, and has been verified to work with the
following compilers:
1. This code creates an instance of pantheios.COM.LoggerManager, then obtains from it an instance of the Console logger, and then logs a simple message to it, obtains a couple of properties from it, and then logs another message.
using vole::object; object loggerManager = object::create("pantheios.COM.LoggerManager"); object logger = loggerManager.invoke_method<object>(L"GetLogger", L"Console", L"VOLE pantheios.COM test"); logger.invoke_method<void>(L"Log", 3, L"The answer is: ", 43); std::string processId = logger.get_property<std::string>(L"ProcessIdentity"); long backEndId = logger.get_property<long>(L"BackEndId"); logger.invoke_method<void>(L"Log", 4, "abc(", L"DEF", "): ", 2319, " - ", 19.19, L" - ", std::string("yada!").c_str());
2. This code drives use the openrj.COM server to open a Record-JAR database file and enumerate its contents:
#include <vole/vole.hpp> #include <comstl/error/errorinfo_desc.hpp> #include <comstl/util/initialisers.hpp> int main(int argc, char *argv[]) { using std::cout; using std::cerr; using std::endl; try { comstl::com_init init; if(argc < 2) { cout << "USAGE: openrj.com.text.exe <db-file>" << endl; } else { using vole::object; using vole::collection; // Create the COM server, via its ProgID "openrj.COM.database" char const *dbFile = argv[1]; collection db = object::create("openrj.COM.database"); // Open the given file db.invoke_method<void>(L"OpenFile", dbFile); // Use the collection::Count property to get the number of records // in the database file, and access the File property via // object::get_property<>() long numRecords = db.Count; std::string fileName = db.get_property<std::string>(L"File"); cout << "Database in file '" << fileName << "' contains " << numRecords << " record(s)" << endl; // Enumerate through the records of the database, via the STL-compatible // collection::iterator class, accessed through the // collection::begin() and collection::end() methods { for(collection::iterator b = db.begin(); b != db.end(); ++b) { // "Convert" the returned VARIANT into a collection collection record(*b); long numFields = record.Count; cout << " Record has " << numFields << " field(s)" << endl; // Enumerate through the fields of the record, via the STL-compatible // collection::iterator class, accessed through the // collection::begin() and collection::end() methods { for(collection::iterator b2 = record.begin(); b2 != record.end(); ++b2) { // "Convert" the returned VARIANT into an object object field(*b2); // Access the Name and Value properties of the // field, via object::get_property<>() std::string name = field.get_property<std::string>(L"Name"); std::string value = field.get_property<std::string>(L"Value"); cout << " " << name << "=" << value << endl; }} }} } } catch(vole::vole_exception &x) { cerr << x.what() << ": " << comstl::errorinfo_desc() << endl; } catch(std::exception &x) { cerr << x.what() << endl; } return 0; }
3. This code creates use a commercial COM Component of Synesis Software to enumerate the NT Services on the host system:
using vole::object; using std::endl; using std::wcout; object ServiceManager = object::create("SynesisSoftware.WindowsNt.ServiceManager"); long timeout = ServiceManager.get_property<long>(L"Timeout"); object Services = ServiceManager.get_property<object>(L"Services"); long numServices = Services.get_property<long>(L"Count"); { for(long i = 0; i < numServices; ++i) { object Service = Services.get_property<object>(L"Item", i); comstl::bstr ServiceName = Service.get_property<comstl::bstr>(L"ServiceName"); comstl::bstr DisplayName = Service.get_property<comstl::bstr>(L"DisplayName"); wcout << L"[" << ServiceName << L"] " << DisplayName << endl << endl; }}