Solod 0.4:改进的C互操作性

Lobsters Hottest 工具

摘要

Solod 0.4通过自动生成绑定、更多独立软件包和为开发者改进的工具,增强了C互操作性。

<p><a href="https://lobste.rs/s/oz5ju3/solod_0_4_better_c_interop">评论</a></p>
查看原文
查看缓存全文

缓存时间: 2026/09/12 14:39

# Solod 0.4:更好的C语言互操作性 来源:https://antonz.org/solod-0.4/ Solod是Go语言的一个子集,可翻译成标准的C代码——无需运行时、采用手动内存管理并支持源代码级互操作。它主要面向两类开发者: - 希望获得底层控制力而又不想学习新语言的Go开发者。 - 喜欢Go语言风格的C开发者。 此次Solod新版本提供了便捷的第三方C库调用方式,使大部分标准库可独立运行,并改进了开发工具链。 - 自动生成绑定 (https://antonz.org/solod-0.4/#automatic-binding-generator) - 独立包 (https://antonz.org/solod-0.4/#more-freestanding-packages) - 类型断言 (https://antonz.org/solod-0.4/#type-assertions) - C语言互操作助手 (https://antonz.org/solod-0.4/#c-interop-helpers) - 多包测试 (https://antonz.org/solod-0.4/#multi-package-testing) - 检查与目标平台 (https://antonz.org/solod-0.4/#checks-and-targets) - Windows支持 (https://antonz.org/solod-0.4/#limited-windows-support) - 总结 (https://antonz.org/solod-0.4/#wrapping-up) ## 自动绑定生成器 Sobind (https://github.com/solod-dev/sobind) 能自动生成绑定——即从Solod调用第三方C库所需的存根代码。它解析`.h`头文件,并生成包含必要结构体、联合体、常量、变量、函数指针类型定义和函数声明的Solod源文件。 随后可在标准Solod代码中使用生成的类型和函数: ``` package main import ( "solod.dev/raylib/libraylib" "solod.dev/so/c" ) func main() { // 使用Raylib绑定。 libraylib.InitWindow(screenWidth, screenHeight, "☀️ Solod / Raylib") defer libraylib.CloseWindow() // ... } ``` 通常生成的绑定可直接使用,无需手动修改。我还为常见C库准备了绑定: - libuv (https://github.com/solod-dev/libuv) - raylib (https://github.com/solod-dev/raylib) - sodium (https://github.com/solod-dev/sodium) - sqlite (https://github.com/solod-dev/sqlite) 与Go不同,从Solod调用C代码毫无性能开销——Solod代码本质上就是标准的C代码。 ## 更多独立包 我曾致力于让尽可能多的包实现独立运行——不依赖任何libc实现或特定操作系统运行时。这一目标进展顺利。Solod目前拥有37个标准库包,其中31个支持独立模式。 以下包可在独立模式下无限制运行: ``` bufio bytealg bytes c cmp encoding encoding/binary encoding/hex encoding/json errors io maps math/bits math/rand mem path runtime slices strconv strings unicode unicode/utf8 unsafe ``` 以下包在独立模式下运行时有一定限制: - `crypto/crand` 依赖用户提供的随机数生成钩子 - `fmt` 依赖用户提供的文本输出钩子 - `math` 提供功能子集 - `net/netip` 可完整运行,但无法解析IPv6区域名 - `sync/atomic` 在支持无锁指令的平台运行 - `testing` 依赖用户提供的测试结果输出钩子 - `time` 通过用户提供的钩子读取时钟 - `uuid` 同时依赖 `crypto/crand` 和 `time` 的钩子 相关详情可参阅单独的文章 (https://antonz.org/going-freestanding/)。 ## 类型断言 现在完全支持对非空接口的逗号-OK模式类型断言: ``` var s1 Shape = &rect r, ok := s1.(*Rect) // r 为 &rect,ok 为 true var s2 Shape = &circle c, ok := s2.(*Rect) // c 为 nil,ok 为 false ``` 对应的C代码如下: ```c main_Shape s1 = (main_Shape){.self = &rect, .Area = main_Rect_Area}; bool ok = (s1.Area == main_Rect_Area); main_Rect* r = ok ? (main_Rect*)s1.self : NULL; // ok == true, r == &rect main_Shape s2 = (main_Shape){.self = &circle, .Area = main_Circle_Area}; ok = (s2.Area == main_Rect_Area); main_Rect* c = ok ? (main_Rect*)s2.self : NULL; // ok == false, c == NULL ``` 此前仅支持直接断言 `r := s.(*Rect)` 和仅检查模式 `_, ok := s.(*Rect)`。 ## C语言互操作助手 `c` 包新增更多常用C类型支持: ``` size_t - c.Size ssize_t - c.SSize ptrdiff_t - c.Ptrdiff intptr_t - c.Intptr long double - c.LongDouble ``` 新增 `c.ConstVoid` 类型,对应C的 `const void`。可在C需要 `const void*` 指针的位置使用: ```c // C代码 so_ssize_t find_first(const void* items, size_t count, size_t size, bool (*match)(const void*)); ``` ``` // Solod代码 //so:extern func find_first(items *c.ConstVoid, count c.Size, size c.Size, match func(item *c.ConstVoid) bool) c.SSize ``` 新增实用的类型转换函数: `c.Bitcast` 可按目标类型重新解释相同大小的值: ```go bits := c.Bitcast[uint64](1.0) // 0x3ff0000000000000 f := c.Bitcast[float64](bits) // 1.0 ``` 可用于替代指针转换如 `*(*float64)(unsafe.Pointer(&b))`。 `c.StringData` 和 `c.SliceData` 返回指向字符串或切片数据的类型化指针: ```go b := []byte{1, 2, 3} p := c.SliceData[c.UChar](b) // unsigned char* q := c.StringData[c.UChar]("ab") // unsigned char* ``` 可替代 `(*T)(unsafe.SliceData(b))` 和 `(*T)(unsafe.StringData(s))`。 ## 多包测试 `so test` 现在支持同时测试多个包。使用以 `...` 结尾的模式时,会自动选择基础目录下所有包含 `test` 子目录的包: ``` so test ./so/... # 整个标准库 so test ./so/net/... # 仅网络相关包 ``` 整个过程只需一次翻译、一次编译、一次执行,比逐包测试更快捷。 使用 `-pkg-file` 标志可限定测试范围: ```text # freestanding.txt so/bytes so/mem so/time ``` ``` so test -pkg-file=freestanding.txt ./so/... ``` ## 检查与目标平台 `so build`、`so test`、`so bench` 和 `so run` 新增两个标志:`-target` 和 `-check`。 `-target` 指定交叉编译的目标平台,使用与 `clang` 和 `zig cc` 的 `--target=` 相同的值: ``` export CC="zig cc" so build -target=x86_64-windows-gnu -o app.exe . so build -target=wasm32-freestanding -o main.wasm . ``` `-check` 启用代码分析: ``` so test -check=warn . # -Wall -Wextra -Werror -Wno-shadow -Wno-unused-label so test -check=sanitize . # warn + AddressSanitizer + UndefinedBehaviorSanitizer so test -check=analyze . # warn + GCC静态分析器 ``` 默认优化级别为 `-O2`,可通过 `CFLAGS` 变量调整。 ## 有限的Windows支持 标准库现已支持 `windows/amd64` 和 `windows/arm64` 目标。所有独立包均可运行,但依赖POSIX的包(`conc`、`flag`、`log/slog`、`net`、`os`、`sync`)暂不支持。 可使用 `zig cc` 交叉编译Windows版本: ``` export CC="zig cc" export CFLAGS="--target=x86_64-windows-gnu" export LDFLAGS="-lbcrypt -liphlpapi" so build -o app.exe . ``` 虽不及Go的Windows支持全面,但已是良好开端。 ## 总结 Solod v0.4 通过自动绑定机制可与几乎所有C库协作。独立感知的标准库使本语言成为嵌入式开发的可行选择。互操作助手提升了C调用代码的可读性,优化的工具链保持测试高效。 当然仍有诸多待办事项。下个版本计划重点完善标准库,引入Go语言的哈希与加密包,并集成更多C库。 若感兴趣,可查阅Solod自述文件 (https://github.com/solod-dev/solod#readme) 获取完整入门指南,或直接 在线体验Solod (https://codapi.org/solod)。 ★ 订阅 (https://antonz.org/subscribe/) 以获取最新文章推送。

相似文章

Solod: Go 可以成为更好的 C

Hacker News Top

Solod 是 Go 的一个严格子集,可编译为可读的 C11,零运行时,无GC,拥有丰富的标准库,让 Go 开发者获得系统级控制,同时为 C 程序员提供熟悉的工具链。

独立运行

Lobsters Hottest

本文介绍了如何将一个名为 Solod 的 Go 到 C 翻译工具变得独立运行的技术,方法是移植标准库包以使其无需 libc 即可工作,使用独立头文件和编译器内建函数等手段。

依赖 Go

Lobsters Hottest

Solod 是一种新的系统编程语言,它是 Go 的一个子集,复用 Go 的工具链和标准库,同时编译为 C11,提供手动内存管理。

Better Sol

Product Hunt

Better Sol 是一款工具,使开发者能够使用 TypeScript 构建端到端的 Solana 应用程序。