Word count: 576, reading time approximately 3 minutes
Zig C++ Interop[1] discusses interoperability between Zig and C++, particularly the issue of sharing data types between the two languages.
The author’s goal is to allow both Zig and C to store each other’s data types within their respective structures/classes, without needing to define all Zig types as external types. Instead, the aim is to use existing types from the standard library and embed them into C types without being constrained by the choice of programming language.
To achieve this, the author proposes a method using the macro <span>SIZED_OPAQUE</span>, which defines an opaque type with a given size and alignment, allowing both languages to embed each other’s types without requiring complete type definitions. This way, the compiler can determine offsets and reserved space. At the same time, both languages can verify the size and alignment of types at compile time.
#define SIZED_OPAQUE(name, size, align)
typedef struct {
_Alignas(align) unsigned char _[size];
} __attribute__((aligned(align))) name;
enum { name##Size = size, name##Align = align }
The article also demonstrates how to use C‘s `shared_ptr` in Zig, and how to move types and access data by defining C functions. The key is to pass the <span>shared_ptr</span> by pointer and avoid direct copying, instead using functions provided by C++ to manipulate it.
Additionally, the author introduces a new pattern by defining the <span>DEFINE_OPAQUE_CONCRETE</span> macro, which creates conversion functions between opaque types and concrete types in C++, simplifying pointer type conversions and improving code readability and safety. This reduces the need for forced type casting and pre-defines the correct conversion methods, making the code clearer and easier to maintain.
#define DEFINE_OPAQUE_CONCRETE(Opaque, Concrete)
Opaque* opaque(Concrete* c) { return reinterpret_cast<Opaque*>(c); }
const Opaque* opaque(const Concrete* c) { return reinterpret_cast<const Opaque*>(c); }
Concrete& concrete(Opaque* o) { return *reinterpret_cast<Concrete*>(o); }
const Concrete& concrete(const Opaque* o) { return *reinterpret_cast<const Concrete*>(o); }
Join Us
The Zig Chinese Community is an open organization dedicated to promoting the use of Zig within the Chinese community, with various ways to get involved:
- 1. Contribute and share[2] your experiences using Zig
- 2. Improve open source projects under the ZigCC organization[3]
- 3. Join WeChat groups[4] and Telegram groups[5]
Reference Links
<span>[1]</span>Zig C++ Interop: https://marler8997.github.io/blog/zig-cpp-interop/<span>[2]</span>Contribute and share: https://ziglang.cc/contributing<span>[3]</span>Open source projects: https://ask.ziglang.cc/github<span>[4]</span>WeChat group: https://ask.ziglang.cc/weixin<span>[5]</span>Telegram group: http://ask.ziglang.cc/telegram