

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 使用適用於 C\$1\$1 的 AWS SDK
<a name="programming-general"></a>

本節提供有關一般使用 的資訊 適用於 C\$1\$1 的 AWS SDK，超出[使用 入門 適用於 C\$1\$1 的 AWS SDK](getting-started.md)的涵蓋範圍。

如需服務特定的程式設計範例，請參閱[適用於 C\$1\$1 的 AWS SDK 程式碼範例](programming-services.md)。

**Topics**
+ [初始化和關閉 SDK](basic-use.md)
+ [提出 AWS 服務 請求](using-service-client.md)
+ [非同步程式設計](async-methods.md)
+ [公用程式模組](utility-modules.md)
+ [記憶體管理](memory-management.md)
+ [處理錯誤](error-handling.md)

# 初始化和關閉 適用於 C\$1\$1 的 AWS SDK
<a name="basic-use"></a>

使用 的應用程式 適用於 C\$1\$1 的 AWS SDK 必須初始化它。同樣地，在應用程式終止之前，必須關閉 SDK。這兩個操作都接受會影響初始化和關閉程序的組態選項，以及對 SDK 的後續呼叫。

使用 的所有應用程式 適用於 C\$1\$1 的 AWS SDK 必須包含 檔案 `aws/core/Aws.h`。

 適用於 C\$1\$1 的 AWS SDK 必須透過呼叫 來初始化 `Aws::InitAPI`。在應用程式終止之前，必須呼叫 關閉 SDK`Aws::ShutdownAPI`。每個方法都接受 的引數[https://docs.aws.amazon.com/sdk-for-cpp/latest/api/aws-cpp-sdk-core/html/struct_aws_1_1_s_d_k_options.html](https://docs.aws.amazon.com/sdk-for-cpp/latest/api/aws-cpp-sdk-core/html/struct_aws_1_1_s_d_k_options.html)。對軟體開發套件的所有其他呼叫可以在這兩個方法呼叫之間執行。

**在 `Aws::InitAPI` 和 之間執行的所有 適用於 C\$1\$1 的 AWS SDK 呼叫`Aws::ShutdownAPI`都應包含在一對大括號內，或應由兩種方法之間呼叫的函數調用。**

基本骨架應用程式如下所示。

```
#include <aws/core/Aws.h>
int main(int argc, char** argv)
{
   Aws::SDKOptions options;
   Aws::InitAPI(options);
   {
      // make your SDK calls here.
   }
   Aws::ShutdownAPI(options);
   return 0;
}
```

**適用於 C\$1\$1 的 SDK 及其相依性使用 C\$1\$1 靜態物件，而靜態物件銷毀的順序並非由 C\$1\$1 標準決定。為了避免靜態變數銷毀的非確定性順序導致的記憶體問題，請勿將對 `Aws::InitAPI`和 的呼叫包裝`Aws::ShutdownAPI`到另一個靜態物件中。 **

# 使用適用於 C\$1\$1 的 AWS SDK 提出 AWS 服務 請求
<a name="using-service-client"></a>

 若要以程式設計方式存取 AWS 服務，SDKs會為每個 使用用戶端類別 AWS 服務。例如，如果您的應用程式需要存取 Amazon EC2，您的應用程式會建立 Amazon EC2 用戶端物件以與該服務連接。然後，您可以使用 服務用戶端向該用戶端提出請求 AWS 服務。

若要向 提出請求 AWS 服務，您必須先建立和[設定](configuring.md)服務用戶端。對於 AWS 服務 您的每個程式碼使用，它都有自己的程式庫和自己的專用類型來與其互動。用戶端會針對服務公開的每個 API 操作公開一個方法。

用戶端類別的命名空間遵循慣例 `Aws::Service::ServiceClient`。例如， AWS Identity and Access Management (IAM) 的用戶端類別為 `Aws::IAM::IAMClient`，Amazon S3 用戶端類別為 `Aws::S3::S3Client`。

所有 AWS 服務的所有用戶端類別都是執行緒安全的。

執行個體化用戶端類別時，必須提供 AWS 憑證。登入資料可從您的程式碼、環境或共用 AWS `config`檔案和共用`credentials`檔案提供。如需登入資料的詳細資訊，請參閱[設定建議 IAM Identity Center 身分驗證的說明](credentials.md)，或使用[其他可用的登入資料提供者](credproviders.md)。

# 使用 進行非同步程式設計 適用於 C\$1\$1 的 AWS SDK
<a name="async-methods"></a>

## 非同步 SDK 方法
<a name="asynchronous-sdk-methods"></a>

對於許多方法，適用於 C\$1\$1 的 SDK 同時提供同步和非同步版本。如果方法在名稱中包含`Async`尾碼，則表示方法為非同步。例如，Amazon S3 方法`PutObject`是同步的，而 `PutObjectAsync`是非同步的。

如同所有非同步操作，非同步 SDK 方法會在其主要任務完成之前傳回 。例如， `PutObjectAsync`方法會在完成將檔案上傳至 Amazon S3 儲存貯體之前傳回 。當上傳操作繼續時，應用程式可以執行其他操作，包括呼叫其他非同步方法。叫用相關聯的回呼函數時，應用程式會收到非同步操作已完成的通知。

下列各節說明程式碼範例，示範呼叫`PutObjectAsync`非同步方法。每個區段著重於範例[整個來源檔案中](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3/put_object_async.cpp)的個別部分。

## 呼叫 SDK 非同步方法
<a name="calling-sdk-asynchronous-methods"></a>

一般而言， SDK 方法的非同步版本接受下列引數。
+ 與同步對等物件相同的請求類型物件的參考。
+ 回應處理常式回呼函數的參考。當非同步操作完成時，會叫用此回呼函數。其中一個引數包含操作的結果。
+ `AsyncCallerContext` 物件`shared_ptr`的選用項目。物件會傳遞至回應處理常式回呼。它包含 UUID 屬性，可用於將文字資訊傳遞至回呼。

以下顯示`uploadFileAsync`的方法會設定並呼叫 SDK 的 Amazon S3 `PutObjectAsync`方法，以非同步方式將檔案上傳至 Amazon S3 儲存貯體。

函數會收到 `S3Client` 物件和 `PutObjectRequest` 物件的參考。它從主要函數接收它們，因為我們需要確保這些物件在整個非同步呼叫期間都存在。

物件`shared_ptr`的 `AsyncCallerContext`已配置。其`UUID`屬性設定為 Amazon S3 物件名稱。基於示範目的，回應處理常式回呼會存取 屬性並輸出其值。

對 的呼叫`PutObjectAsync`包含回應處理常式回呼函數 的參考引數`uploadFileAsyncFinished`。下一節會更詳細地檢查此回呼函數。

```
bool AwsDoc::S3::uploadFileAsync(const Aws::S3::S3Client &s3Client,
                                Aws::S3::Model::PutObjectRequest &request,
                                const Aws::String &bucketName,
                                const Aws::String &fileName) {
    request.SetBucket(bucketName);
    request.SetKey(fileName);

    const std::shared_ptr<Aws::IOStream> input_data =
            Aws::MakeShared<Aws::FStream>("SampleAllocationTag",
                                          fileName.c_str(),
                                          std::ios_base::in | std::ios_base::binary);

    if (!*input_data) {
        std::cerr << "Error: unable to open file " << fileName << std::endl;
        return false;
    }

    request.SetBody(input_data);

    // Create and configure the context for the asynchronous put object request.
    std::shared_ptr<Aws::Client::AsyncCallerContext> context =
            Aws::MakeShared<Aws::Client::AsyncCallerContext>("PutObjectAllocationTag");
    context->SetUUID(fileName);

    // Make the asynchronous put object call. Queue the request into a 
    // thread executor and call the uploadFileAsyncFinished function when the
    // operation has finished. 
    s3Client.PutObjectAsync(request, uploadFileAsyncFinished, context);

    return true;
}
```

非同步操作的資源必須存在，直到操作完成為止。例如，用戶端和請求物件必須存在，直到應用程式收到操作已完成的通知。在非同步操作完成之前，應用程式本身無法終止。

因此， `uploadFileAsync`方法接受 `S3Client`和 `PutObjectRequest` 物件的參考，而不是在 `uploadFileAsync`方法中建立它們，並將它們儲存在本機變數中。

在此範例中， `PutObjectAsync`方法會在開始非同步操作後立即傳回給發起人，讓呼叫鏈能夠在上傳操作進行時執行其他任務。

如果用戶端存放在 `uploadFileAsync`方法的本機變數中，則會在傳回方法時超出範圍。不過，用戶端物件必須繼續存在，直到非同步操作完成為止。

## 非同步操作完成通知
<a name="notification-of-the-completion-of-an-asynchronous-operation"></a>

當非同步操作完成時，會叫用應用程式回應處理常式回呼函數。此通知包含 操作的結果。結果會包含在方法同步對等項目傳回的相同結果類型類別中。在程式碼範例中，結果位於 `PutObjectOutcome` 物件中。

範例的回應處理常式回呼函數`uploadFileAsyncFinished`如下所示。它會檢查非同步操作是否成功或失敗。它使用 `std::condition_variable`來通知應用程式執行緒非同步操作已完成。

```
// A mutex is a synchronization primitive that can be used to protect shared
// data from being simultaneously accessed by multiple threads.
std::mutex AwsDoc::S3::upload_mutex;

// A condition_variable is a synchronization primitive that can be used to
// block a thread, or to block multiple threads at the same time.
// The thread is blocked until another thread both modifies a shared
// variable (the condition) and notifies the condition_variable.
std::condition_variable AwsDoc::S3::upload_variable;
```

```
void uploadFileAsyncFinished(const Aws::S3::S3Client *s3Client,
                            const Aws::S3::Model::PutObjectRequest &request,
                            const Aws::S3::Model::PutObjectOutcome &outcome,
                            const std::shared_ptr<const Aws::Client::AsyncCallerContext> &context) {
    if (outcome.IsSuccess()) {
        std::cout << "Success: uploadFileAsyncFinished: Finished uploading '"
                  << context->GetUUID() << "'." << std::endl;
    } else {
        std::cerr << "Error: uploadFileAsyncFinished: " <<
                  outcome.GetError().GetMessage() << std::endl;
    }

    // Unblock the thread that is waiting for this function to complete.
    AwsDoc::S3::upload_variable.notify_one();
}
```

完成非同步操作後，即可釋出與其相關聯的資源。如有需要，應用程式也可以終止。

下列程式碼示範應用程式如何使用 `uploadFileAsync`和 `uploadFileAsyncFinished`方法。

應用程式會配置 `S3Client`和 `PutObjectRequest` 物件，使其持續存在，直到非同步操作完成為止。呼叫 後`uploadFileAsync`，應用程式可以執行所需的任何操作。為了簡化，範例使用 `std::mutex`和 `std::condition_variable` 等待回應處理常式回呼通知它上傳操作已完成。

```
int main(int argc, char* argv[])
{
    if (argc != 3)
    {
        std::cout << R"(
Usage:
    run_put_object_async <file_name> <bucket_name>
Where:
    file_name - The name of the file to upload.
    bucket_name - The name of the bucket to upload the object to.
)" << std::endl;
        return 1;
    }

    const Aws::SDKOptions options;
    Aws::InitAPI(options);
    {
        const Aws::String fileName = argv[1];
        const Aws::String bucketName = argv[2];

        // A unique_lock is a general-purpose mutex ownership wrapper allowing
        // deferred locking, time-constrained attempts at locking, recursive
        // locking, transfer of lock ownership, and use with
        // condition variables.
        std::unique_lock<std::mutex> lock(AwsDoc::S3::upload_mutex);

        // Create and configure the Amazon S3 client.
        // This client must be declared here, as this client must exist
        // until the put object operation finishes.
        const Aws::S3::S3ClientConfiguration config;
        // Optional: Set to the AWS Region in which the bucket was created (overrides config file).
        // config.region = "us-east-1";

        const Aws::S3::S3Client s3Client(config);

        // Create the request object.
        // This request object must be declared here, because the object must exist
        // until the put object operation finishes.
        Aws::S3::Model::PutObjectRequest request;

        AwsDoc::S3::uploadFileAsync(s3Client, request, bucketName, fileName);

        std::cout << "main: Waiting for file upload attempt..." <<
                  std::endl << std::endl;

        // While the put object operation attempt is in progress,
        // you can perform other tasks.
        // This example simply blocks until the put object operation
        // attempt finishes.
        AwsDoc::S3::upload_variable.wait(lock);

        std::cout << std::endl << "main: File upload attempt completed."
                  << std::endl;
    }
    Aws::ShutdownAPI(options);

    return 0;
}
```

請參閱 GitHub 上的[完整範例](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3/put_object_async.cpp)。

# 中的公用程式模組 適用於 C\$1\$1 的 AWS SDK
<a name="utility-modules"></a>

 適用於 C\$1\$1 的 AWS SDK 包含許多[公用程式模組](https://docs.aws.amazon.com/sdk-for-cpp/latest/api/aws-cpp-sdk-core/html/namespace_aws_1_1_utils.html)，可減少在 C\$1\$1 中開發 AWS 應用程式的複雜性。

## HTTP 堆疊
<a name="http-stack"></a>

提供連線集區的 HTTP 堆疊可安全執行緒，並可視需要重複使用。如需詳細資訊，請參閱[AWS 用戶端組態](client-config.md)。


****  

|  |  | 
| --- |--- |
|  標頭  |   [https://github.com/aws/aws-sdk-cpp/tree/master/aws-cpp-sdk-core/include/aws/core/http](https://github.com/aws/aws-sdk-cpp/tree/master/aws-cpp-sdk-core/include/aws/core/http)   | 
|  API 文件  |   [https://docs.aws.amazon.com/sdk-for-cpp/latest/api/aws-cpp-sdk-core/html/namespace_aws_1_1_http.html](https://docs.aws.amazon.com/sdk-for-cpp/latest/api/aws-cpp-sdk-core/html/namespace_aws_1_1_http.html)   | 

## String Utils
<a name="string-utils"></a>

核心字串函數，例如 `trim`、 `lowercase`和數值轉換。


****  

|  |  | 
| --- |--- |
|  標頭  |   [https://github.com/aws/aws-sdk-cpp/tree/master/aws-cpp-sdk-core/include/aws/core/utils/StringUtils.h](https://github.com/aws/aws-sdk-cpp/tree/master/aws-cpp-sdk-core/include/aws/core/utils/StringUtils.h)   | 
|  API 文件  |   [https://docs.aws.amazon.com/sdk-for-cpp/latest/api/aws-cpp-sdk-core/html/class_aws_1_1_utils_1_1_string_utils.html](https://docs.aws.amazon.com/sdk-for-cpp/latest/api/aws-cpp-sdk-core/html/class_aws_1_1_utils_1_1_string_utils.html)   | 

## 雜湊 Utils
<a name="hashing-utils"></a>

雜湊函數，例如 `SHA256`、`Base64`、 `MD5`和 `SHA256_HMAC`。


****  

|  |  | 
| --- |--- |
|  標頭  |   [https://github.com/aws/aws-sdk-cpp/tree/master/aws-cpp-sdk-core/include/aws/core/utils/HashingUtils.h](https://github.com/aws/aws-sdk-cpp/tree/master/aws-cpp-sdk-core/include/aws/core/utils/HashingUtils.h)   | 
|  API 文件  |   [https://docs.aws.amazon.com/sdk-for-cpp/latest/api/aws-cpp-sdk-core/html/class_aws_1_1_utils_1_1_hashing_utils.html](https://docs.aws.amazon.com/sdk-for-cpp/latest/api/aws-cpp-sdk-core/html/class_aws_1_1_utils_1_1_hashing_utils.html)   | 

## JSON 剖析器
<a name="json-parser"></a>

功能完整但輕量的 JSON 剖析器 （圍繞 的薄包裝函式*`cJSON`*)。


****  

|  |  | 
| --- |--- |
|  標頭  |   [https://github.com/aws/aws-sdk-cpp/tree/master/aws-cpp-sdk-core/include/aws/core/utils/json/JsonSerializer.h](https://github.com/aws/aws-sdk-cpp/tree/master/aws-cpp-sdk-core/include/aws/core/utils/json/JsonSerializer.h)   | 
|  API 文件  |   [https://docs.aws.amazon.com/sdk-for-cpp/latest/api/aws-cpp-sdk-core/html/class_aws_1_1_utils_1_1_json_1_1_json_value.html](https://docs.aws.amazon.com/sdk-for-cpp/latest/api/aws-cpp-sdk-core/html/class_aws_1_1_utils_1_1_json_1_1_json_value.html)   | 

## XML 剖析器
<a name="xml-parser"></a>

輕量型 XML 剖析器 （圍繞 的薄包裝函式*`tinyxml2`*)。[RAII 模式](http://en.cppreference.com/w/cpp/language/raii)已新增至界面。


****  

|  |  | 
| --- |--- |
|  標頭  |   [https://github.com/aws/aws-sdk-cpp/tree/master/aws-cpp-sdk-core/include/aws/core/utils/xml/XmlSerializer.h](https://github.com/aws/aws-sdk-cpp/tree/master/aws-cpp-sdk-core/include/aws/core/utils/xml/XmlSerializer.h)   | 
|  API 文件  |   [https://docs.aws.amazon.com/sdk-for-cpp/latest/api/aws-cpp-sdk-core/html/namespace_aws_1_1_utils_1_1_xml.html](https://docs.aws.amazon.com/sdk-for-cpp/latest/api/aws-cpp-sdk-core/html/namespace_aws_1_1_utils_1_1_xml.html)   | 

# 中的記憶體管理 適用於 C\$1\$1 的 AWS SDK
<a name="memory-management"></a>

 適用於 C\$1\$1 的 AWS SDK 提供一種方法來控制程式庫中的記憶體配置和解除配置。

**注意**  
只有在您使用使用定義的編譯時間常數 建置的程式庫版本時，才能使用自訂記憶體管理`USE_AWS_MEMORY_MANAGEMENT`。  
如果您使用在沒有編譯時間常數的情況下建置的程式庫版本，例如 的全域記憶體系統函數`InitializeAWSMemorySystem`將無法運作；而是使用全域 `new`和 `delete`函數。

如需編譯時間常數的詳細資訊，請參閱 [STL 和 AWS 字串和向量](#stl-and-aws-strings-and-vectors)。

## 配置和解除配置記憶體
<a name="allocating-and-deallocating-memory"></a>

 **配置或取消配置記憶體** 

1. 子類別`MemorySystemInterface`：`aws/core/utils/memory/MemorySystemInterface.h`。

   ```
   class MyMemoryManager : public Aws::Utils::Memory::MemorySystemInterface
   {
   public:
       // ...
       virtual void* AllocateMemory(
           std::size_t blockSize, std::size_t alignment,
           const char *allocationTag = nullptr) override;
       virtual void FreeMemory(void* memoryPtr) override;
   };
   ```
**注意**  
您可以`AllocateMemory`視需要變更 的類型簽章。

1. 使用 `Aws::SDKOptions` 結構來設定自訂記憶體管理員的使用。將結構的執行個體傳遞至 `Aws::InitAPI`。在應用程式終止之前，必須使用`Aws::ShutdownAPI`相同的執行個體呼叫 來關閉 SDK。

   ```
   int main(void)
   {
     MyMemoryManager sdkMemoryManager;
     SDKOptions options;
     options.memoryManagementOptions.memoryManager = &sdkMemoryManager;
     Aws::InitAPI(options);
   
     // ... do stuff
   
     Aws::ShutdownAPI(options);
   
     return 0;
   }
   ```

## STL 和 AWS 字串和向量
<a name="stl-and-aws-strings-and-vectors"></a>

使用記憶體管理員初始化時， 會將所有配置和解除配置 適用於 C\$1\$1 的 AWS SDK 延遲至記憶體管理員。如果記憶體管理員不存在，開發套件會使用全域新增和刪除。

如果您使用自訂 STL 分配器，則必須變更所有 STL 物件的類型簽章，以符合配置政策。由於 STL 在 SDK 實作和界面中顯著使用，因此 SDK 中的單一方法會禁止將預設 STL 物件直接傳遞至 SDK 或控制 STL 配置。或者，混合式方法在內部使用自訂分配器，並允許界面上的標準和自訂 STL 物件，可能會使調查記憶體問題更加困難。

解決方案是使用記憶體系統的編譯時間常數`USE_AWS_MEMORY_MANAGEMENT`來控制開發套件使用的 STL 類型。

如果啟用編譯時間常數 （開啟），則類型會解析為具有連接到 AWS 記憶體系統的自訂分配器的 STL 類型。

如果停用編譯時間常數 （關閉），所有`Aws::*`類型都會解析為對應的預設`std::*`類型。

 **開發套件中 `AWSAllocator.h` 檔案的範例程式碼** 

```
#ifdef USE_AWS_MEMORY_MANAGEMENT

template< typename T >
class AwsAllocator : public std::allocator< T >
{
   ... definition of allocator that uses AWS memory system
};

#else

template< typename T > using Allocator = std::allocator<T>;

#endif
```

在範例程式碼中， `AwsAllocator` 可以是自訂分配器或預設分配器，取決於編譯時間常數。

 **開發套件中 `AWSVector.h` 檔案的範例程式碼** 

```
template<typename T> using Vector = std::vector<T, Aws::Allocator<T>>;
```

在範例程式碼中，我們會定義`Aws::*`類型。

如果啟用編譯時間常數 （開啟），則類型會使用自訂記憶體配置和 AWS 記憶體系統對應至向量。

如果停用編譯時間常數 （關閉），則類型會映射到`std::vector`具有預設類型參數的規則。

類型別名用於 SDK 中執行記憶體配置的所有`std::`類型，例如容器、字串串流和字串緩衝區。 適用於 C\$1\$1 的 AWS SDK 使用這些類型。

## 剩餘問題
<a name="remaining-issues"></a>

您可以在 SDK 中控制記憶體配置；不過，STL 類型仍然會透過對模型物件`initialize`和`set`方法的字串參數來主導公有界面。如果您不使用 STL 並改用字串和容器，則每當您想要進行服務呼叫時，都必須建立許多臨時項目。

為了在使用非 STL 進行服務呼叫時移除大多數臨時和配置，我們實作了以下內容：
+ 每個接受字串的 Init/Set 函數都有一個需要 的過載`const char*`。
+ 每個採用容器的 Init/Set 函數 （映射/向量） 都有一個採用單一項目的新增變體。
+ 每個接受二進位資料的 Init/Set 函數都有一個過載，該過載會將指標指向資料和`length`值。
+ （選用） 每個接受字串的 Init/Set 函數都有一個過載，其需要一個非零的終止`const char*`和一個`length`值。

## 原生 SDK 開發人員和記憶體控制
<a name="native-sdk-developers-and-memory-controls"></a>

請遵循 SDK 程式碼中的下列規則：
+ 請勿使用 `new`和 `delete`；請`Aws::Delete<>`改用 `Aws::New<>`和 。
+ 請勿使用 `new[]`和 `delete[]`；請使用 `Aws::NewArray<>`和 `Aws::DeleteArray<>`。
+ 請勿使用 `std::make_shared`；請使用 `Aws::MakeShared`。
+ 將 `Aws::UniquePtr`用於單一物件的唯一指標。使用 `Aws::MakeUnique`函數建立唯一的指標。
+ 將 `Aws::UniqueArray`用於物件陣列的唯一指標。使用 `Aws::MakeUniqueArray`函數建立唯一的指標。
+ 不要直接使用 STL 容器；使用其中一個 `Aws::` typedefs 或為您想要的容器新增 typedef。例如：

  ```
  Aws::Map<Aws::String, Aws::String> m_kvPairs;
  ```
+ `shared_ptr` 用於傳遞至 SDK 並受其管理的任何外部指標。您必須使用符合物件配置方式的銷毀政策來初始化共用指標。如果 SDK 預期不會清除指標，您可以使用原始指標。

# 處理適用於 C\$1\$1 的 AWS SDK 中的錯誤
<a name="error-handling"></a>

 適用於 C\$1\$1 的 AWS SDK 不使用例外狀況；不過，您可以在程式碼中使用例外狀況。每個服務用戶端都會傳回結果物件，其中包含結果和錯誤代碼。

 **處理錯誤條件的範例** 

```
bool CreateTableAndWaitForItToBeActive()
{
  CreateTableRequest createTableRequest;
  AttributeDefinition hashKey;
  hashKey.SetAttributeName(HASH_KEY_NAME);
  hashKey.SetAttributeType(ScalarAttributeType::S);
  createTableRequest.AddAttributeDefinitions(hashKey);
  KeySchemaElement hashKeySchemaElement;
  hashKeySchemaElement.WithAttributeName(HASH_KEY_NAME).WithKeyType(KeyType::HASH);
  createTableRequest.AddKeySchema(hashKeySchemaElement);
  ProvisionedThroughput provisionedThroughput;
  provisionedThroughput.SetReadCapacityUnits(readCap);
  provisionedThroughput.SetWriteCapacityUnits(writeCap);
  createTableRequest.WithProvisionedThroughput(provisionedThroughput);
  createTableRequest.WithTableName(tableName);

  CreateTableOutcome createTableOutcome = dynamoDbClient->CreateTable(createTableRequest);
  if (createTableOutcome.IsSuccess())
  {
     DescribeTableRequest describeTableRequest;
     describeTableRequest.SetTableName(tableName);
     bool shouldContinue = true;
     DescribeTableOutcome outcome = dynamoDbClient->DescribeTable(describeTableRequest);

     while (shouldContinue)
     {
         if (outcome.GetResult().GetTable().GetTableStatus() == TableStatus::ACTIVE)
         {
            break;
         }
         else
         {
            std::this_thread::sleep_for(std::chrono::seconds(1));
         }
     }
     return true;
  }
  else if(createTableOutcome.GetError().GetErrorType() == DynamoDBErrors::RESOURCE_IN_USE)
  {
     return true;
  }

  return false;
}
```