C++ Builder

RAD Server and the included Data Storage for RAD Server Users

Embarcadero’s RAD Server Enterprise Mobility Server (EMS) is a turn-key application foundation for rapidly building and deploying services based applications. RAD Server’s core offerings include automated Delphi and C++ REST/JSON API publishing and management, Enterprise database integration middleware, IoT Edgeware and an array of application services such as User Directory and Authentication services, Push Notifications, Indoor/Outdoor Geolocation and JSON data storage. RAD Server enables developers to quickly build new application back-ends or migrate existing Delphi or C++ client/server business logic to a modern services based architecture that is open, stateless, secure and scalable. RAD Server is easy to develop, deploy and operate making it ideally suited for ISVs and OEMs building re-deployable solutions. Two important and useful features included with RAD Server are: 1. It’s important to note that a RAD Server single site license (included in Enterprise Edition) still allows you to deploy a solution based on multiple instances of the RAD Server engine, on multiple physical or virtual servers, for fail-over and load balancing, as long as they are backed by a single instance of the RAD Server database (the included InterBase database instance) which manages the RAD Server license itself. 2. It’s also important to note that Data Storage for Users in the form of JSON name/value pairs is part of the core RAD Server offering. But the use of the included RAD Server InterBase database as a relational DB is subject to a separate license (and also the installation of a separate InterBase server instance). This post focuses on how to use RAD Server to add JSON data storage, to create some Custom Fields to store additional JSON name-value information for your RAD Server Users. The included RAD Server InterBase database creates a USERS table. The RAD Server USERS Table allows you to manage the RAD Server Users data that are stored in your RAD Server Engine (EMS Server). The USERS Table stores information about RAD Server Users in the RAD Server Engine (EMS Server): The RAD Server USERS table columns are listed here: /* Table: USERS, Owner: SYSDBA */ CREATE TABLE USERS ( UID INTEGER NOT NULL, TID INTEGER NOT NULL, USERID CHAR(36) NOT NULL, USERNAME VARCHAR(32) NOT NULL, HPASSWORD CHAR(32), SALT CHAR(6), SESSIONID CHAR(32), SESSIONTIME TIMESTAMP, ISACTIVE BOOLEAN DEFAULT TRUE, CREATED TIMESTAMP, LASTMODIFIED TIMESTAMP, CREATOR CHAR(36), UNIQUE (USERID), PRIMARY KEY (UID), CONSTRAINT USERS_UNIQ UNIQUE (USERNAME, TID) ); ALTER TABLE USERS ADD CONSTRAINT TUSERS FOREIGN KEY (TID) REFERENCES TENANTS (TID); /* Meta data descriptions. This syntax requires InterBase 2020 or higher. Some tables require ODS18 and higher */ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 /* Table: USERS, Owner: SYSDBA */ CREATE TABLE USERS (         UID INTEGER NOT NULL,         TID INTEGER NOT NULL,         USERID CHAR(36) NOT NULL,         USERNAME VARCHAR(32) NOT NULL,         HPASSWORD CHAR(32),         SALT CHAR(6),         SESSIONID CHAR(32),         SESSIONTIME TIMESTAMP,         ISACTIVE BOOLEAN DEFAULT TRUE,         CREATED TIMESTAMP,         LASTMODIFIED TIMESTAMP,         CREATOR CHAR(36), UNIQUE (USERID), PRIMARY KEY (UID), CONSTRAINT USERS_UNIQ UNIQUE (USERNAME, TID) ); ALTER TABLE USERS ADD CONSTRAINT TUSERS FOREIGN KEY (TID) REFERENCES TENANTS (TID); /* Meta data descriptions.   This syntax requires InterBase 2020 or higher.   Some tables require ODS18 and higher */ The UID is the USERID is a Unique identifier of a RAD Server User (UserID) in the RAD Server […]

Read More

Learn How To Use C++ Defaulted Functions For Windows Development With C++ Builder

A defaulted function is a function that contains =default; in its prototype. This construction indicates that the function’s default definition should be used. Defaulted functions are a C++11 specific feature. Defaulted functions example class A { A() = default; // OK A& operator = (A & a) = default; // OK void f() = default; // ill-formed, only special member function may be defaulted }; class A {         A() = default;                    // OK         A& operator = (A & a) = default;  // OK         void f() = default;               // ill-formed, only special member function may be defaulted }; By default, C++ provides four default special member functions. Users may override these defaults. destructor default constructor copy constructor copy assignment operator = Also by default, C++ applies several global operators to classes. Users may provide class-specific operators. sequence operator , address-of operator & indirection operator * member access operator -> member indirection operator ->* free-store allocation operator new free-store deallocation operator delete The management of defaults has several problems: Constructor definitions are coupled; declaring any constructor suppresses the default constructor. The destructor default is inappropriate to polymorphic classes, requiring an explicit definition. Once a default is suppressed, there is no means to resurrect it. Default implementations are often more efficient than manually specified implementations. Non-default implementations are non-trivial, which affects type semantics, e.g. makes a type non-POD. There is no means to prohibit a special member function or global operator without declaring a (non-trivial) substitute. The most common encounter with these problems is when disabling copying of a class. The accepted technique is to declare a private copy constructor and a private copy assignment operator, and then fail to define either. Head over and check out more information about defaulted functions on Windows in C++.

Read More

Quickly Write Efficient Code With Modern Structured Bindings Available In C++17 On Windows With C++Builder

C++17 has a new feature that consolidates syntactic sugar and automatic type deduction: structured bindings. This helps to assign values from tuples, pairs, and structs into individual variables. In another programming language, you can find this as unpacking. Applying a structured binding to specify various variables from one bundled structure is one step. Structured bindings always applied with the same pattern: auto [var1, var2, …] = ; auto [var1, var2, …] = pair, tuple, struct, or array expression>; The list of variables var1, var2 – must exactly match the number of variables contained by the expression being assigned from Then there should be one of the following std::pair std::tuple struct or array The type can be auto, const auto, or even auto&& If you write too many or not enough variables between the square brackets, the compiler will give an error, telling us about our mistake std::tuple tup {3.55, 1, 99}; auto [a, b] = tup; // gives an error std::tuplefloat, int, long> tup {3.55, 1, 99}; auto [a, b] = tup; // gives an error Here is a complete real example of a use case for structured bindings: #ifdef _WIN32 #include #else typedef char _TCHAR; #define _tmain main #endif #include #include #include // Demonstrate structured bindings – here, a method might in the past // have had a bool success result, and an error param written to. // Now, can return both (all error info) as one tuple, bound automatically // to local vars through the auto keyword (much nicer than std::tie // in C++11/14) auto connect_to_network() { // The connection could succeed, or fail with an error message // Here, mimic it failing bool connected{ false }; // failed! std::string str_error{ “404: resource not found” }; return std::make_tuple(connected, str_error); } int _tmain(int argc, _TCHAR* argv[]) { auto [connected, str_error] = connect_to_network(); if (!connected) { std::cout 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 #ifdef _WIN32 #include #else typedef char _TCHAR; #define _tmain main #endif   #include #include #include   // Demonstrate structured bindings – here, a method might in the past // have had a bool success result, and an error param written to. // Now, can return both (all error info) as one tuple, bound automatically // to local vars through the auto keyword (much nicer than std::tie // in C++11/14)   auto connect_to_network() {   // The connection could succeed, or fail with an error message   // Here, mimic it failing   bool connected{ false }; // failed!     std::string str_error{ “404: resource not found” };     return std::make_tuple(connected, str_error); }   int _tmain(int argc, _TCHAR* argv[]) {   auto [connected, str_error] = connect_to_network();     if (!connected) {     std::cout str_error;   }     system(“pause”);     return 0; } As you can see, by using structured bindings, you can write more efficient and clean code. Be sure to check out the official documentation on structured bindings here! Check out the structured bindings demo for C++Builder on GitHub!

Read More

Learn How To Use Python Functions With Keyword Arguments In A Delphi Windows App

rocedure TForm1.Button1Click(Sender: TObject); var   P : Variant; begin   PythonEngine1.ExecStrings( Memo1.Lines );   P := MainModule.Person(‘John’, ‘Doe’);   Assert(P.first_name = ‘John’);   Assert(P.last_name = ‘Doe’);   Assert(VarIsNone(P.weight));   Assert(VarIsNone(P.height));   Assert(VarIsNone(P.age));   P := MainModule.Person(‘John’, ‘Doe’, weight := 70);   Assert(P.first_name = ‘John’);   Assert(P.last_name = ‘Doe’);   Assert(P.weight = 70);   Assert(VarIsNone(P.height));   Assert(VarIsNone(P.age));   P := MainModule.Person(‘John’, ‘Doe’, weight := 70, height := 172);   Assert(P.first_name = ‘John’);   Assert(P.last_name = ‘Doe’);   Assert(P.weight = 70);   Assert(P.height = 172);   Assert(VarIsNone(P.age));   P := MainModule.Person(‘John’, ‘Doe’, weight := 70, height := 172, age := 35);   Assert(P.first_name = ‘John’);   Assert(P.last_name = ‘Doe’);   Assert(P.weight = 70);   Assert(P.height = 172);   Assert(P.age = 35);   P := MainModule.Person(last_name := ‘Doe’, first_name := ‘John’, weight := 70, height := 172, age := 35);   Assert(P.first_name = ‘John’);   Assert(P.last_name = ‘Doe’);   Assert(P.weight = 70);   Assert(P.height = 172);   Assert(P.age = 35);   P := MainModule.Person(‘John’, ‘Doe’, 35, 172, 70);   Assert(P.first_name = ‘John’);   Assert(P.last_name = ‘Doe’);   Assert(P.weight = 70);   Assert(P.height = 172);   Assert(P.age = 35);   Memo2.Lines.Add(‘Success’) end;

Read More

Learn How To Solve The C++ SFINAE Problem For Expressions In Windows Development With C++ Builder

Substitution failure is not an error (SFINAE) refers to a situation in C++ where an invalid substitution of template parameters is not in itself an error. We’re talking here about something related to templates, template substitution rules and metaprogramming… A quick example: template struct A {}; char xxx(int); char xxx(float); template A f(T){} int main() { f(1); }   template <int I> struct A {};     char xxx(int);   char xxx(float);     template <class T> A<sizeof(xxx((T)0))> f(T){}     int main()   {     f(1);   } This example is rejected by all major compilers because template deduction/substitution has historically used a simplified model of semantic checking, i.e., the SFINAE rules (which are mostly about types), instead of full semantic checking. But in C++ 11, fully general expressions allowed, and that most errors in such expressions be treated as SFINAE failures rather than errors. There’s a continuum of errors, some errors being clearly SFINAE failures, and some clearly “real” errors, with lots of unclear cases in between. We decided it’s easier to write the definition by listing the errors that are not treated as SFINAE failures, and the list we came up with is as follows: errors that occur while processing some entity external to the expression, e.g., an instantiation of a template or the generation of the definition of an implicitly-declared copy constructor. errors due to implementation limits (it’s probably a category error to list these here, since they’re not errors in the normal sense, but we wanted to make it very clear that compilers don’t have to take steps to capture and recover from violations of implementation limits; such violations cause hard errors, compiler crashes, etc., the same as anywhere else in a program). errors due to access violations (this is a judgment call, but the philosophy of access has always been that it doesn’t affect visibility)Everything else produces a SFINAE failure rather than a hard error. At certain points in the template argument deduction process it is is necessary to take a function type that makes use of template parameters and replace those template parameters with the corresponding template arguments. This is done at the beginning of template argument deduction when any explicitly specified template arguments are substituted into the function type, and again at the end of template argument deduction when any template arguments that were deduced or obtained from default arguments are substituted. The substitution occurs in all types and expressions that are used in the function type and in template parameter declarations. The expressions include not only constant expressions such as those that appear in array bounds or as nontype template arguments but also general expressions (i.e., non-constant expressions) inside sizeof, decltype, and other contexts that allow non-constant expressions. [Note: The equivalent substitution in exception specifications is done only when the function is instantiated, at which point a program is ill-formed if the substitution results in an invalid type or expression.] For example, template auto f(T t1, T t2) -> decltype(t1 + t2); template <class T> auto f(T t1, T t2) -> decltype(t1 + t2); Head over and check out more information about SFINAE problems for expressions in Windows Development.

Read More

Easily Use A Popular Python Image Library In A Delphi Windows GUI App

procedure TForm1.Button2Click(Sender: TObject); var   _im : Variant;   _stream : TMemoryStream;   _dib : Variant;   pargs: PPyObject;   presult :PPyObject;   P : PAnsiChar;   Len : NativeInt; begin   if (Image1.Picture.Graphic = nil) or Image1.Picture.Graphic.Empty then     raise Exception.Create(‘You must first select an image’);   PythonEngine1.ExecStrings(Memo1.Lines);   _im := MainModule.ProcessImage(ImageToPyBytes(Image1.Picture.Graphic));   if not chkUseDC.Checked then   begin     // We have to call PyString_AsStringAndSize because the image may contain zeros     with GetPythonEngine do begin       pargs := MakePyTuple([ExtractPythonObjectFrom(_im)]);       try         presult := PyEval_CallObjectWithKeywords(             ExtractPythonObjectFrom(MainModule.ImageToBytes), pargs, nil);         try           if (P = nil) or (PyBytes_AsStringAndSize(presult, P, Len) 0) then begin             ShowMessage(‘This does not work and needs fixing’);             Abort;           end;         finally           Py_XDECREF(pResult);         end;       finally         Py_DECREF(pargs);       end;     end;       _stream := TMemoryStream.Create();     try       _stream.Write(P^, Len);       _stream.Position := 0;       Image1.Picture.Graphic.LoadFromStream(_stream);     finally       _stream.Free;     end;   end   else   begin     Image1.Picture.Bitmap.SetSize(Image1.Width, Image1.Height);     _dib := Import(‘PIL.ImageWin’).Dib(_im);     Image1.Picture.Bitmap.SetSize(Image1.Height, Image1.Width);     _dib.expose(NativeInt(Image1.Picture.Bitmap.Canvas.Handle));   end; end;

Read More

Stunning Cross-Platform FireMonkey App Profile Templates Available For Android And iOS From GetIt

This FireMonkey UI template includes three different designs for implementing an app profile screen in a multi-device application. As you can see, these are the app profile Delphi/C++ Builder FireMonkey samples. From these sample app profile demos, you can learn how to design and build beautiful responsive FireMonkey applications by just dragging and dropping the components. Sample features Available on Delphi and C++ Builder TFrame TLayout TRectangle  and other components You can download these samples from GetIt Package Manager Also, be sure to check out other FireMonkey and VCL sample applications on GetIt

Read More

Delphi and C++Builder 10.4.2 Beta Invite for Update Subscription Customers

We are pleased to invite all of our RAD Studio customers with an active subscription to the NDA beta program for Embarcadero’s 10.4.2 release of Delphi, C++Builder, and RAD Studio, codenamed “Hunter”. RAD Studio 10.4.2 builds on the great features introduced in RAD Studio 10.4 and 10.4.1, and adds new features and enhancements throughout the product.  To learn more about the capabilities we have planned for the 10.4.2 release, please refer to the RAD Studio November 2020 Roadmap PM Commentary blog post (please note that features mentioned in the blog post are not committed until completed and GA released). After you have joined the beta, you will receive additional documentation detailing the features of each beta build. How to join:  To participate in the beta, please provide your name and the email address associated with your Update Subscription (the email you used to register the product) using this form by Tuesday, December 15, 2020. Once you’ve provided your email address, you will receive a follow-up email in the second half of December with a link to electronically sign the Hunter Beta NDA. After signing the NDA, you will be provided with the information needed to participate in the 10.4.2 beta. Please note that 10.4.2 beta builds cannot be installed on the same machine as your current 10.4 or 10.4.1 Sydney installation (also, we generally recommend against installing beta versions on a production machine).   Not current on subscription but interested in joining the 10.4.2 beta? Contact your Embarcadero sales representative or reseller partner to renew your subscription and be invited to join the beta program. 

Read More

Learn About Using Alignment Support In C++Builder For Robust Windows Development

The alignment requirement of a type is a divisor of its size. For example, a class with size 16 bytes could have an alignment of 1, 2, 4, 8, or 16, but not 32. (If a class’s members only total 14 bytes in size, but the class needs to have an alignment requirement of 8, the compiler will insert 2 padding bytes to make the class’s size equal to 16.). C++11 standard intends to extend the standard language and library with alignment-related features. Querying the alignment of a type The alignment requirement of a type can be queried using the alignof keyword as a unary operator. The result is a constant expression of type std::size_t, i.e., it can be evaluated at compile time. #include int main() { std::cout #include int main() {     std::cout << “The alignment requirement of int is: “ << alignof(int) << ‘n’; } Possible output : The alignment requirement of int is: 4 Controlling alignment The alignas keyword can be used to force a variable, class data member, declaration or definition of a class, or declaration or definition of an enum, to have a particular alignment, if supported. It comes in two forms: alignas(x), where x is a constant expression, gives the entity the alignment x, if supported.alignas(T), where T is a type, gives the entity an alignment equal to the alignment requirement of T, that is, alignof(T), if supported. If multiple alignas specifiers are applied to the same entity, the strictest one applies. In this example, the buffer buf is guaranteed to be appropriately aligned to hold an int object, even though its element type is unsigned char, which may have a weaker alignment requirement. alignas(int) unsigned char buf[sizeof(int)]; new (buf) int(42); alignas(int) unsigned char buf[sizeof(int)]; new (buf) int(42); alignas cannot be used to give a type a smaller alignment than the type would have without this declaration: alignas(1) int i; //Il-formed, unless `int` on this platform is aligned to 1 byte. alignas(char) int j; //Il-formed, unless `int` has the same or smaller alignment than `char`. alignas(1) int i; //Il-formed, unless `int` on this platform is aligned to 1 byte. alignas(char) int j; //Il-formed, unless `int` has the same or smaller alignment than `char`. Head over and check out more information about C++ alignment support in C++Builder.

Read More

Learn How To Build An Iterator Python Type For Delphi In This Windows GUI App

We are aware of how to use TStringList in Delphi. we learned how to create a Python type using Delphi classes. Thinking How to create an iterator in Delphi Which holds python objects? This post guide you to create a Python Type that contains a list of strings(python string objects) similar to TStringList. And a String List Iterator Python Type In Delphi to iterate the StringList Python Type easily in Delphi with Python4Delphi Sample App. Python4Delphi Demo28 Sample App shows how to create a StringList Python type, StringList Iterator Python Type in a Python Module, Import the module, and Iterator Python Types in a python script, create a Stringlist object and access some of the service routines like Iter, IterNext, etc. You can find the Demo28 source on GitHub. Prerequisites: Download and install the latest Python for your platform. Follow the Python4Delphi installation instructions mentioned here. Alternatively, you can check out this video Getting started with Python4Delphi. Components used in Python4Delphi Demo28 Sample App: TPythonEngine: A collection of relatively low-level routines for communicating with Python, creating Python types in Delphi, etc. It’s a singleton class. TPythonGUIInputOutput: Inherited from TPythonInputOutput (which works as a console for python outputs) Using this component Output property you can associate the Memo component to show the Output. TPythonModule: It’s inherited from TMethodsContainer class allows creating modules by providing a name. You can use routines AddMethod, AddMethodWithKW, AddDelphiMethod, AddDelphiMethodWithKeywords to add a method which should be type compatible with this routine parameter. You can create events using the Events property. TPythonType: This component helps to create a new python type in Delphi which is inherited from the hierarchy of classes (set of APIs to create, manage methods, and members). TMemo: A multiline text editing control, providing text scrolling. The text in the memo control can be edited as a whole or line by line. You can find the Python4Delphi Demo28 sample project from the extracted repository ..Python4DelphiDemosDemo28.dproj. Open this project in RAD Studio 10.4.1 and run the application. Implementation Details: PythonEngine1 provides the connection to Python or rather the Python API. This project uses Python3.9 which can be seen in the TPythonEngine DllName property. PythonGUIInputOutput1 provides a conduit for routing input and output between the Graphical User Interface (GUI) and the currentlyexecuting Python script. pmP4D with a Module name p4d is created. Python Type (ptStringList) with Type Name TStringList and Python type (ptStringListIterator) with Type Name TStringListIterator is created. Both Python Types Module Property is assigned with pmP4D. Each Python Type PyObjectClass is initialized with Delphi Python Type Class as shown below. procedure TForm1.ptStringListCreate(Sender: TObject); begin with Sender as TPythonType do PyObjectClass := TPyStringList; end; procedure TForm1.ptStringListIteratorCreate(Sender: TObject); begin with Sender as TPythonType do PyObjectClass := TPyStringListIterator; end; procedure TForm1.ptStringListCreate(Sender: TObject); begin   with Sender as TPythonType do     PyObjectClass := TPyStringList; end;   procedure TForm1.ptStringListIteratorCreate(Sender: TObject); begin   with Sender as TPythonType do     PyObjectClass := TPyStringListIterator; end; In this sample, TPyStringList overrides the Iter, Basic service of TPyObject, and Sequence Services such as SqLength, SqItem, SqAsItem. Using RegisterMethods exposed an Add method(Using this a string can be added to the string list). Used PyArg_ParseTuple to retrieve the arguments passed in python scripts. This class also has the property to return TStringList. function TPyStringList.add(args: PPyObject): PPyObject; var _obj : PPyObject; begin with GetPythonEngine do begin // We adjust the transmitted self argument Adjust(@Self); if PyArg_ParseTuple( args, ‘O:add’,@_obj ) 0 then begin Result := PyLong_FromLong(Strings.Add(PyObjectAsString(_obj))); end else […]

Read More