Closed7

Zigを使ってSourceModのextensionを記述したかった

FlowingSPDGFlowingSPDG

モチベーション:
現行のSourceエンジンのプラグイン開発はSourceModのプラグイン開発が主流
ただし、SourcePawn自体がかなり古い言語なので、C++を書くときのような苦痛が結構ある
ネイティブプラグインの開発や、MetaMod:Sourceからの開発はC++で記述する必要があり、負担が大きい
SourceModのextensionであれば、SourcePawnからの利用も可能かつ、SourceModからのEvent/Forwardを上手く活用しつつ、SourcePawnより低レイヤーの処理が記述出来る
C++のインターフェースに従っていれば開発は可能そうではあるので、自身のC++経験がかなり浅いことと、なんとなくZigが気になっていたので、実用性と開発効率をいったん無視して開発してみる。

FlowingSPDGFlowingSPDG

Zigの経験が浅いので、GitHub Copilotに助けを求める。

deferがブロック外で記載されていたり、client変数がint型だったのでi32に修正したりなどして出来たコードが以下。

const std = @import("std");
const c = @cImport({
    @cInclude("smsdk_ext.h");
});

// イベントハンドラ
pub fn onChatHandler(client: i32, text: []const u8) void {
    std.debug.print("Chat message received from client {}: {}\n", .{ client, text });
}

// Forwardの定義
const OnChat = c.defineForward("OnChat", .{});

// イベントの登録
pub fn registerEvents() void {
    defer c.finalizeForward(OnChat);
    c.registerEvent(OnChat, .{&onChatHandler});
}

以下コマンドで、取り急ぎコンパイルが通ることを確認。
動作確認は実施していない。

zig build-lib -dynamic -target x86_64-linux-gnu ext.zig
FlowingSPDGFlowingSPDG

コンパイルしたライブラリを csgo-dedicated/csgo/addons/sourcemod/extensions に放り込む。
名前は拡張子は .ext.so である必要があり、ロード時は拡張子を省略する必要がある。
したがって、成果物のファイル名を libext.ext.so にして、以下コマンドでロードしてみる。

sm exts load libext
[SM] Extension libext.ext.so failed to load: Unable to find extension entry point

エントリーポイントが見つからないと怒られた。

FlowingSPDGFlowingSPDG

GetSMExtAPI のシンボルアドレスが見つからない際に発生するエラーのようだ。
smsdk_ext.h に含まれていたが、さらにsourcepawnのincludeにも依存しているため、正しくインクルードしてtranslateするMakefileを作成した。

build:
	zig build-lib -dynamic -target x86-linux-gnu src/ext.zig -lc -lsmsdk_ext

translate:
	zig translate-c -lc \
		-I/mnt/c/Users/Flowing/Documents/GitHub/sourcemod-sample-ext-zig/sdk/sourcemod/public \
		-I/mnt/c/Users/Flowing/Documents/GitHub/sourcemod-sample-ext-zig \
		-I/mnt/c/Users/Flowing/Documents/GitHub/sourcemod-sample-ext-zig/sdk/sourcepawn/include \
		/mnt/c/Users/Flowing/Documents/GitHub/sourcemod-sample-ext-zig/sdk/sourcemod/public/smsdk_ext.h > src/smsdk_ext.zig

ここで問題発生。
そもそも根本の勘違いとして、ZigはC++ではなくCとの互換をサポートしている。
そして、そもそもSourceMod SDKはC++だった。なぜ気付かなかった...

FlowingSPDGFlowingSPDG

いったん諦めて、別スクラップにてRustを使って同じことが出来ないか試してみようと思う。

このスクラップは2023/09/23にクローズされました