AWS Developer Blog

AWS SDK for C++: Simplified Configuration and Initialization

by Jonathan Henson | on | in C++, C++ | Permalink | Comments |  Share

Many of our users are confused by initializing and installing a memory manager, enabling logging, overriding the HTTP stack, and installing custom cryptography implementations. Not only are these tasks confusing, they are tedious and require an API call to set up and tear down each component. To make matters worse, on some platforms, we were silently initializing libCurl and OpenSSL. This caused the AWS SDK for C++ to mutate static global state, creating problems for the programs that relied on it.

As of version 0.12.x, we have added a new initialization and shutdown process. We have added the structure Aws::SDKOptions to store each of the SDK-wide configuration options. You can use SDKOptions to set a memory manager, turn on logging, provide a custom logger, override the HTTP implementation, and install your own cryptography implementation at runtime. By default, this structure has all of the settings you are used to, but manipulating those options should now be more clear and accessible.

This change has a few side effects.

  • First, the HTTP factory is now globally installed instead of being passed to service-client constructors. It doesn’t really make sense to force the HTTP client factory through each client; if this setting is being customized, it will be used across the SDK.
  • Second, you can turn on logging simply by setting the logging level.
  • Third, if your application is already using OpenSSL or libCurl, you have the option of bypassing their initialization in the SDK entirely. This is particularly useful for legacy applications that need to interoperate with the AWS SDK.
  • Finally, all code using the SDK must call the Aws::InitAPI() function before making any other API calls and the Aws::ShutdownAPI() function when finished using the SDK. If you do not call these new functions, your application may crash for all SDK versions later than 0.12.x.

Here are a few recipes:


#include <aws/core/Aws.h>

Just use the default configuration:


   SDKOptions options;
   Aws::InitAPI(options);
   //make your SDK calls in here.
   Aws::ShutdownAPI(options);

Turn logging on using the default logger:


   SDKOptions options;
   options.loggingOptions.logLevel = Aws::Utils::Logging::LogLevel::Info;
   Aws::InitAPI(options);
   //make your SDK calls in here.
   Aws::ShutdownAPI(options);

Install a custom memory manager:


    MyMemoryManager memoryManager;

    SDKOptions options;
    options.memoryManagementOptions.memoryManager = &memoryManager;
    Aws::InitAPI(options);
    //make your SDK calls in here.
    Aws::ShutdownAPI(options);

Override the default HTTP client factory:


    SDKOptions options;
    options.httpOptions.httpClientFactory_create_fn = [](){ return Aws::MakeShared<MyCustomHttpClientFactory>("ALLOC_TAG", arg1); };
    Aws::InitAPI(options);
    //make your SDK calls in here
    Aws::ShutdownAPI(options);

Note: SDKOptions::HttpOptions takes a closure instead of a std::shared_ptr. We do this for all of the factory functions because the memory manager will not have been installed at the time you will need to allocate this memory. You pass your closure to the SDK, and it is called when it is safe to do so. This simplest way to do this is with a Lambda expression.

As we get ready for General Availability, we wanted to refine our initialization and shutdown scheme to be flexible for future feature iterations and new platforms. This update will allow us to provide new features without breaking users. We welcome your feedback about how we can improve this feature.