1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Zig言語でAppKitのコードをフルスクラッチで書くのはかなり骨が折れそうだと思った件

Last updated at Posted at 2023-01-04

冬休みの自由研究に AppKitをC言語でフルスクラッチ記述している jimon/osx_app_in_plain_c をzig言語で写経してたのですが、ハマりどころをメモとして残しておきます。

事象

Objective-Cのメッセージ送信は最終的にobjc/message.hで宣言されているobjc_msgSendに行き着くが、このプロトタイプ宣言が

void objc_msgSend(void);

であり、使用用途に応じて関数ポインタを型キャストして使用してねというスタンスの模様。

例えば、NSWindowのインスタンス化なら、

id objc_msgSend(id, SEL, NSRect, NSUInteger, NSUInteger, BOOL) {

}

となる。

これならzigのcomptime活かせそうだと思い、comptimeな展開結果を意識して

fn new_window_msgSend(self: id, selector: SEL, arg1: NSRect, arg2: NSUInteger, arg3: NSUInteger, arg4: BOOL) id {
    const FuncType = fn (@TypeOf(self), @TypeOf(selector), @TypeOf(arg1), @TypeOf(arg2), @TypeOf(arg3), @TypeOf(arg4)) callconv(.C) id;

    var func = @ptrCast(FuncType, objc_msgSend);

    return @call(.{}, func .{ id, selector, rect, arg1, arg2, arg3, arg4 });
}

としたところ、なぜかウインドウが表示されない・・・。

また

2023-01-04 22:00:28.375 osx_app_in_plain_ziglang[52798:1855657] NSWindow does not support nonactivating panel styleMask 0x80
2023-01-04 22:00:28.375 osx_app_in_plain_ziglang[52798:1855657] NSWindow does not support utility styleMask 0x10

なログが実行時に表示される始末。

原因

zig言語では最適化の兼ね合いでstructを引数に渡す場合、参照渡しにするというのがあり。
ここにモロに引っかかった模様

対処

comptimeの道を諦め、C言語

id new_window_msgSend(id alloc, SEL selector, NSRect rect, NSUInteger styleMask, NSUInteger backing, BOOL defer) {
	return ((id (*)(id, SEL, NSRect, NSUInteger, NSUInteger, BOOL))objc_msgSend)(alloc, selector, rect, styleMask, backing, defer);
}

を用意しておいた上で、

zig言語からがextern関数で参照するという泥臭い方法をとった。

extern "C" fn new_window_msgSend(self: id, selector: SEL, arg1: NSRect, arg2: NSUInteger, arg3: NSUInteger, arg4: BOOL) id;

extern関数であれば、C ABIが採用されるためうまくいった模様。

レポジトリ

写経結果は、

に残しておいた。

コメントほとんど書いていないので読めた代物ではないが、zig言語でのBindingの足がかり程度に見て貰えば幸いである。

あと、Application Bundleのために作ったbuild taskは有用かも。

2023/01/18 追記

以下のissueですでに報告され、修正がmasterブランチにはすでに取り込まれている模様。

現時点のstableである0.10.0にはまだ反映されていないが、2023/01/18付で公開されたmasterのプリビルド1で反映されていることを確認した。

  1. もしかしてNightly Buildで毎日公開されてる?

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?