Generics Collections TDictionary (C++)
Contents
Description
This example shows how to handle Delphi generics from a C++ application.
To build and test this example:
- Create a Delphi package where you can instantiate a TDictionary:
- Create a new Delphi package, and save it as "DelphiPackage".
- Add a new Delphi unit to your package, and save this unit as "DelphiUnit".
- Create a C++ console application to load and show your Delphi resource string:
- On the Projects Window, right-click your project group and select Add New Project.
- On the New Items dialog box, select C++Builder Projects on the tree view and, on the list of C++Builder projects, select Console Application and click OK.
- On the New Console Application dialog box that opens, click OK to use the default C++ console application settings.
- Save your main C++ file as "main.cpp", your precompiled header file as "CppApplicationPCH.h", and your project as "CppApplication".
- Select Project > Options > C++ Linker and enable the "Link with the Delphi Runtime Library" option.
Code
Copy the following code in your DelphiUnit.pas file:
unit DelphiUnit;
interface
uses
System.Generics.Collections;
type
TCity = class
Country: String;
Latitude: Double;
Longitude: Double;
end;
// You cannot use TDictionary<String, TCity> in C++ unless you first
// instantiate it in Delphi as follows:
CityDictionary = class(TDictionary<String, TCity>)
end;
implementation
end.
Then right-click your DelphiPackage project on the Project Manager and select Build.
Add the generated Delphi package library file to your C++ console application:
- Right-click your CppApplication project on the Project Manager and select Add.
- On the dialog box that opens, select the DelphiPackage.lib file that you previously built and click OK. You may find this file inside "C:\Users\Public\Documents\Embarcadero\Studio\22.0\Dcp".
- Note: If you cannot see the expected file, ensure that the file filter in the dialog box is "Any file (*.*)".
Copy the following code in your main.cpp file:
#pragma hdrstop
#pragma argsused
#ifdef _WIN32
#include <tchar.h>
#else
typedef char _TCHAR;
#define _tmain main
#endif
#include <iostream>
#include <DelphiUnit.hpp>
const double EPSILON = 0.0000001;
int _tmain(int argc, _TCHAR* argv[])
{
// Create the dictionary.
TDictionary__2<UnicodeString, TCity*>* dictionary = new TDictionary__2<UnicodeString, TCity*>(0);
TCity* city;
// Add some key-value pairs to the dictionary.
city = new TCity;
city->Country = "Romania";
city->Latitude = 47.16;
city->Longitude = 27.58;
dictionary->Add("Iasi", city);
city = new TCity;
city->Country = "United Kingdom";
city->Latitude = 51.5;
city->Longitude = -0.17;
dictionary->Add("London", city);
city = new TCity;
city->Country = "Argentina";
city->Latitude = 0; // Wrong coordinates
city->Longitude = 0; // on purpose.
dictionary->Add("Buenos Aires", city);
// Display the current number of key-value entries.
std::wcout << "Number of pairs in the dictionary: " << dictionary->Count << "." << std::endl;
// Try looking up "Iasi".
if (dictionary->TryGetValue("Iasi", city))
std::wcout << "Iasi is located in " << city->Country
<< " with latitude = " << city->Latitude
<< " and longitude = " << city->Longitude
<< "." << std::endl;
else
std::wcout << "Could not find Iasi in the dictionary." << std::endl;
// Remove the "Iasi" key from the dictionary.
dictionary->Remove("Iasi");
// Make sure that the capacity of the dictionary is set to the number of entries.
dictionary->TrimExcess();
// Test if "Iasi" is a key in the dictionary.
if (dictionary->ContainsKey("Iasi"))
std::wcout << "The key \"Iasi\" is in the dictionary." << std::endl;
else
std::wcout << "The key \"Iasi\" is not in the dictionary." << std::endl;
if (dictionary->ContainsKey("London")) {
// Test how (United Kingdom, 51.5, -0.17) is a value in the dictionary...
dictionary->TryGetValue("London", city);
if (city->Country == "United Kingdom" && (city->Latitude - 51.5) < EPSILON && (city->Longitude - -0.17) < EPSILON)
std::wcout << "The value (United Kingdom, 51.5, -0.17) is in the dictionary." << std::endl;
else
std::wcout << "Error: The value (United Kingdom, 51.5, -0.17) is not in the dictionary." << std::endl;
// ...but ContainsValue returns False if passed a different instance of
// TCity with the same data, as different instances have different references.
city = new TCity;
city->Country = "United Kingdom";
city->Latitude = 51.5;
city->Longitude = -0.17;
if (dictionary->ContainsValue(city))
std::wcout << "Error: A new instance of TCity with values (United Kingdom, 51.5, -0.17) matches an existing instance in the dictionary." << std::endl;
else
std::wcout << "A new instance of TCity with values (United Kingdom, 51.5, -0.17) does not match any existing instance in the dictionary." << std::endl;
delete city;
}
else {
std::wcout << "Error: The key \"London\" is not in the dictionary." << std::endl;
}
// Update the coordinates to the correct ones.
city = new TCity;
city->Country = "Argentina";
city->Latitude = -34.6;
city->Longitude = -58.45;
dictionary->AddOrSetValue("Buenos Aires", city);
// Generate the exception "Duplicates not allowed".
try {
dictionary->Add("Buenos Aires", city);
} catch (Exception &e) {
std::wcout << "Could not add entry. Duplicates are not allowed." << std::endl;
}
// Display all countries.
std::wcout << "All countries:" << std::endl;
DynamicArray<TCity*> cityValues = dictionary->Values->ToArray();
const int cityCount = cityValues.get_length();
for (int i = 0; i < cityCount; i++) {
std::wcout << cityValues[i]->Country << std::endl;
}
// Iterate through all keys in the dictionary and display their coordinates.
std::wcout << "All cities and their coordinates:" << std::endl;
DynamicArray<UnicodeString> cityKeys = dictionary->Keys->ToArray();
for (int i = 0; i < cityCount; i++) {
dictionary->TryGetValue(cityKeys[i], city);
std::wcout << cityKeys[i] << ": " << city->Latitude << ", " << city->Longitude << std::endl;
}
// Clear all entries in the dictionary.
dictionary->Clear();
// There should be no entries at this point.
std::wcout << "Number of key-value pairs in the dictionary after cleaning: " << dictionary->Count << std::endl;
std::cin.get();
return 0;
}
Now you can run your C++ console application. A console should open and display the following output:
Number of pairs in the dictionary: 3. Iasi is located in Romania with latitude = 47.16 and longitude = 27.58. The key "Iasi" is not in the dictionary. The value (United Kingdom, 51.5, -0.17) is in the dictionary. A new instance of TCity with values (United Kingdom, 51.5, -0.17) does not match any existing instance in the dictionary. Could not add entry. Duplicates are not allowed. All countries: United Kingdom Argentina All cities and their coordinates: London: 51.5, -0.17 Buenos Aires: -34.6, -58.45 Number of key-value pairs in the dictionary after cleaning: 0
Uses
- System.Generics.Collections.TDictionary ( fr | de | ja )
- System.Generics.Collections.TDictionary.Keys ( fr | de | ja )
- System.Generics.Collections.TDictionary.Values ( fr | de | ja )
- System.Generics.Collections.TDictionary.Add ( fr | de | ja )
- System.Generics.Collections.TDictionary.AddOrSetValue ( fr | de | ja )
- System.Generics.Collections.TDictionary.Clear ( fr | de | ja )
- System.Generics.Collections.TDictionary.ContainsKey ( fr | de | ja )
- System.Generics.Collections.TDictionary.ContainsValue ( fr | de | ja )
- System.Generics.Collections.TDictionary.Remove ( fr | de | ja )
- System.Generics.Collections.TDictionary.TrimExcess ( fr | de | ja )