如何将C++标准库集成到Zig程序中?

11
阅读 zig 文档时,我认为 zig 可以编译 C 和 C++ 代码。因此,我认为你可以通过@cImport导入 C++ 文件的头文件,并使zig build成功。但是,我似乎无法将其用于 C++ 库集成。
我首先创建项目 zig init-lib,然后通过@cImport指令将我的导入添加到src/main.zig中。具体来说,我@cInclude("hooks/hooks.h")了该库的 C++ 头文件。如果此时尝试进行zig build,则构建将失败,因为找不到头文件。我通过修改build.zig并使用lib.addIncludeDir("/usr/include/library")来解决这个问题。
由于现在正在解析此 C++ 库并且使用 C++ 标准库,所以当我zig build时,下一个错误是找不到stdexcept头文件。为了解决这个问题,我修改build.zig并使用lib.linkSystemLibrary("c++")
最后,卡在的错误是出现在/path/to/zig-linux-x86_64-0.9.1/lib/libcxx/include/<files>中的一系列错误。我得到类似于unknown type name '__LIBCPP_PUSH_MACROSunknown type name 'namespace'unknown type name 'template'的内容。通过谷歌搜索,我只能找到部分相关的内容,即这是由于clang默认将.h文件解释为C文件而不是C++文件导致的,显然不具有namespacetemplate关键字,但我不知道如何处理这些信息。LLVM on MacOs - unknown type name 'template' in standard file iosfwd 有人了解如何通过 zig 真正与 C++(而不是纯C)库集成吗?
1个回答

10
具体来说,我使用@cInclude("hooks/hooks.h")这个库的C++头文件。
@cImport()用于将C头文件转换为Zig,以便在不编写绑定的情况下使用它们。不幸的是,它不支持C++头文件。要使用C++库,您必须为其编写C绑定,然后再使用@cImport()导入这些头文件。
// src/bindings.cpp
#include <iostream>

extern "C" void doSomeCppThing(void) {
    std::cout << "Hello, World!\n";
}

// src/bindings.h
void doSomeCppThing(void);

// build.zig
const std = @import("std");

pub fn build(b: *std.build.Builder) void {
    const target = b.standardTargetOptions(.{});

    const optimize = b.standardOptimizeOption(.{});

    const exe = b.addExecutable(.{
        .name = "tmp",
        .root_source_file = .{ .path = "src/main.zig" },
        .target = target,
        .optimize = optimize,
    });

    exe.linkLibC();
    exe.linkLibCpp();    
    exe.addIncludePath("src");
    exe.addCSourceFile("src/bindings.cpp", &.{});

    b.installArtifact(exe);
}

// src/main.zig
const c = @cImport({
    @cInclude("bindings.h");
});

pub fn main() !void {
    c.doSomeCppThing();
}

为了实现一个处理程序,我试图使用kea hooks/hooks.h头文件。在你的例子中,似乎重点是接口应该是纯C的,无论实现是否包括C ++。在这种情况下,我仍然有点困惑。即使有一个C接口,如果你的C++代码包括<stdexcept>,随后libcxx/include/cstddef,那么你仍然会遇到我遇到的解析错误,其中zig无法识别“template”或“namespace”。 - Ambiguous Illumination
@AmbiguousIllumination 如果头文件被设计为与C兼容,那么头文件将不包括stdexcept,而是实现将包括它。从hooks.h看来,它似乎是设计用于被C++代码包含的,因为它有命名空间并使用C++特性:https://github.com/isc-projects/kea/blob/master/src/lib/hooks/hooks.h - pfg
1
如果您的C++代码包含<stdexcept>,那么使用C接口,就不会出现解析错误。因为C++代码是在build.zig文件中使用addCSourceCode()编译的,这可以处理C++代码。而C头文件则是通过@cImport解析的,它无法处理C++代码。 - pfg
好的,我现在会将这个标记为答案。我会尝试实验,看看是否能够正确创建纯C接口来满足我需要的少量C++功能,假设这不超出我的技能范围。 - Ambiguous Illumination

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接