Would you like to add C++ to your Delphi application? Or add Delphi code to your C++ application? Here’s how.
One thing you might not know is how closely integrated the C++ and Delphi languages are in RAD Studio. You can compile a single application in a single project to a single EXE, mixing both languages. (And of course you can do so using DLLs or packages as well.) If you use C++Builder, this is useful to add Delphi-implemented libraries. If you use Delphi, you might want to use portions of C++ to take advantage of C++ libraries, or perhaps the LLVM optimizer.
For CodeRage XI (2016), I gave a presentation on mixing Delphi and C++ code. The talk is online, but this blog post also discusses how to mix the two and also gives source code.
There are two areas: adding Delphi to a C++Builder project, and adding C++ to a Delphi project.
Adding Delphi to C++Builder
You can add any .pas file to a C++ project. (C++Builder has supported adding Pascal files into a C++ project for many years, since at least CB2006.) When you add a Pascal file and build the C++ project, the .pas files are built before any C++ files, and the Delphi compiler auto-generates a C++ header with a .hpp extension. This is exactly the same as the headers for the VCL or FMX! This allows C++ code to refer to Delphi classes and types, completely unaware they are not implemented in C++, and at link time the Delphi code is linked in to C++ code.
Delphi and C++ are ABI compatible. In fact, you can even create C++ classes that inherit from Delphi classes. Delphi language extensions such as ARC, closures, etc are supported in our C++ compilers. Combined with header generation, this means the two languages can interoperate seamlessly, and it’s very easy for C++ to call Delphi code. You do this every time you write a UI using the VCL, in fact.
Adding C++ to Delphi
The reverse, calling C++ code from Delphi, is also possible although slightly more complicated. There’s no equivalent to the header generation of Delphi code to declare C++ code to Delphi. Delphi has no concept of headers, for example. The closest is the interface section of a unit – and what would a unit look like that was a translation of C++ code?
The video instead shows one technique, which I personally recommend, to call from Delphi code into C++. Define an abstract base class in Delphi, and then in a package, inherit from it and implement it in C++. This gives you an interface defined in Delphi, an instance of which you can use in Delphi as though it was a Delphi object, but that is actually implemented in C++.
C++Builder supports packages, and that leads to elegant code separation. In the video, the C++ class is implemented in the package, combined with a factory method which Delphi can call to create an instance. In the C++ class, you can use any C++ you want – one common question from customers is, “Are you limited in the C++ features you can use if you’re using the class from Delphi?” The answer is no, you’re not limited. Delphi sees only the interface defined in Delphi, and types it can understand. In the implementation, including in the header of the derived class, you can use any C++ you want to.
This is a very powerful technique to add C++ to your Delphi applications. You might want to do this for a number of reasons, such as to use C++ libraries, or to make use of the LLM optimizations on Windows for, eg, math code.
Note that having both Delphi and C++ projects requires you to have both Delphi and C++Builder – that is, RAD Studio, which costs less than the two individually. A good deal, giving you access to powerful code!
Mixing two languages at the natively compiled, binary level, ABI-compatible, no runtime, is a very powerful feature. The video is worth watching: it goes into depth about the techniques, including the reasons for them, and shows an explains the code in the projects.
You can find the example projects on Github. There are three projects:
- Starting with a C++ project, call into Delphi code:
- CPP_Call_Delphi: a C++ project with a .pas file added
- Starting with a Delphi project, call into C++ code:
- Delphi_Call_CPP: a Delphi project which defines an abstract base class, and calls into a package
- CPPPackage: a C++ package which implements the abstract class, returns an instance of it to Delphi code, and does various things in C++ to demonstrate the use of C++, regardless of the fact it’s called by Delphi