Skip to content

【Zig 日报】Zig 与 C++ 交互的新方法 #276

@jiacai2050

Description

@jiacai2050

Zig C++ Interop 一文讨论了在 Zig 和 C++ 之间进行互操作,特别是在两种语言之间共享数据类型的问题。

作者的目标是允许 Zig 和 C++ 都能够在各自的结构体/类中存储对方的数据类型,并且不希望将所有 Zig 类型定义为外部类型,而是希望使用标准库中的现有类型,并能将它们嵌入到 C++ 类型中,而不受编程语言选择的限制。

为了实现这一点,作者提出了一种使用宏 SIZED_OPAQUE 的方法,该宏定义了一个具有给定大小和对齐方式的不透明类型,允许两种语言嵌入对方的类型,而无需完整的类型定义。这样,编译器可以确定偏移量和保留空间。同时,两种语言都可以在编译时验证类型的大小和对齐方式。

#define SIZED_OPAQUE(name, size, align)                  \
    typedef struct {                                     \
        _Alignas(align) unsigned char _[size];           \
    } __attribute__((aligned(align))) name;              \
    enum { name##Size = size, name##Align = align }

文章还展示了如何在 Zig 中使用 C++ 的 shared_ptr,以及如何通过定义 C++ 函数来移动类型和访问数据。关键在于使用指针传递 shared_ptr,并避免直接复制,而是通过 C++ 提供的函数来操作。

此外,作者还介绍了一种新的模式,通过定义 DEFINE_OPAQUE_CONCRETE 宏,在 C++ 中创建不透明类型和具体类型之间的转换函数,以简化指针类型转换,提高代码可读性和安全性。这减少了强制类型转换的需要,并预先定义了正确的转换方式,使代码更加清晰和易于维护。

#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); }

加入我们

Zig 中文社区是一个开放的组织,我们致力于推广 Zig 在中文群体中的使用,有多种方式可以参与进来:

  1. 供稿,分享自己使用 Zig 的心得
  2. 改进 ZigCC 组织下的开源项目
  3. 加入微信群Telegram 群组

Metadata

Metadata

Assignees

No one assigned

    Labels

    日报daily report

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions