C++ ABI Compatibility

From RAD Studio
Jump to: navigation, search

What is an ABI

An Application Binary Interface (ABI) defines how binary components interact at runtime. ABIs include calling conventions, exception handling, type layouts, and more. Since C++ does not support a standardized ABI, different compilers may produce incompatible binaries.

For stability, it is recommended to compile C++ code using the same toolchain. If interoperability is necessary, use C interfaces or COM.

For more information on ABI, see Application Binary Interface

ABI Compiler Support

RAD Studio compiler supports the following:

  • Win64 calling convention
  • COFF for object files and DLLs.

C Code Compatibility

When writing in Plain Old C (POC), the following works seamlessly:

  • POC libraries
  • DLLs with a POC interface: functions exported via extern “C”)
```c  
extern "C" {  
   __declspec(dllexport) int add_numbers(int a, int b);  
}  
```

C++ Code Compatibility

C++ has no standardized Application Binary Interface (ABI); therefore, mixing compilers can be risky. It is recommended to build using the RAD Studio compiler. The following are some of the risks explained.

Name Mangling Differences

The RAD Studio compiler uses Itanium name mangling], which is the cross-platform standard. Vendors may use different toolchains that can make things different; for example, MSVC uses its own mangling scheme. Therefore, even if the COFF format matches, the symbols may not be linked.

Standard Library (STL) Incompatibilities

RAD Studio uses LLVM’s libc++, a cross-platform STL. Vendors may use different toolchains, which can make things different. For example, MSVC uses its own STL, such as: msvcprt.lib, msvcp140.dll, and more.

This means that the implementation of, say, a std::vector is different, so it is not possible to link to code using a std::vector because, while the user-facing name is the same, the underlying implementation, layout, etc, is different. This is true for all C++ types, with std::vector being an example.

Runtime Behavior Differences

ABI mismatches can occur even if linking succeeds. It is not guaranteed that the ABI is the same. Some causes are mentioned below:

  • Incorrect memory layout. In memory layout may be different inside types.
  • Undefined behavior in exception handling.
  • Runtime instability that may be hard to track down.
Note: It is recommended to build with the same compiler that is being used for linking.
Attention: It is strongly recommended to rebuild all C++ code with RAD Studio’s compiler to ensure ABI compatibility.

Using COM

If rebuilding is not an option, you can wrap it in a COM object using the steps below.

COM provides a stable binary interface across compilers.

  1. Use COM interfaces to expose your C++ functionality.
  2. Use IDL to define a contract between components.
  3. Clients can consume the COM object regardless of the compiler used.
Attention: COM adds complexity; it is recommended to only use this if rebuilding is not possible.

See Also