Zig'de C makro yansıtması
(jstrieb.github.io)Zig'de C makro yansıtması
-
Zig
- Zig, düşük seviye ve sistem programlamaya odaklanan yeni bir programlama dilidir ve C'nin yerini alabilecek bir dil olarak konumlanmaktadır
- Hâlâ geliştirme aşamasında olsa da Bun ve TigerBeetle gibi projelerde şimdiden kullanılmaktadır
- Zig'in en etkileyici özelliklerinden biri C ile mükemmel birlikte çalışabilirliğidir
-
Harici kütüphaneleri çağırma
- Zig'de harici kütüphaneleri çağırmak kolaydır
- Örnek kod:
const win = @import("std").os.windows; extern "user32" fn MessageBoxA(?win.HWND, [*:0]const u8, [*:0]const u8, u32,) callconv(win.WINAPI) i32; pub fn main() !void { _ = MessageBoxA(null, "world!", "Hello", 0); }
-
C header dosyalarını içe aktarma
- Zig'de C header dosyaları içe aktarılıp normal bir Zig import'u gibi kullanılabilir
- Örnek kod:
const win32 = @cImport({ @cInclude("windows.h"); @cInclude("winuser.h"); }); pub fn main() !void { _ = win32.MessageBoxA(null, "world!", "Hello", 0); }
-
Windows programlama
- Tipik bir Windows uygulamasında bir
mainfonksiyonu ve bir window procedure fonksiyonu bulunur mainfonksiyonu uygulamayı başlatır ve mesajları window procedure'a ileten döngüyü çalıştırır- window procedure gelen mesajları alıp işler
- Örnek kod:
const std = @import("std"); const windows = std.os.windows; const win32 = @cImport({ @cInclude("windows.h"); @cInclude("winuser.h"); }); var stdout: std.fs.File.Writer = undefined; pub export fn WindowProc(hwnd: win32.HWND, uMsg: c_uint, wParam: win32.WPARAM, lParam: win32.LPARAM) callconv(windows.WINAPI) win32.LRESULT { _ = switch (uMsg) { win32.WM_CLOSE => win32.DestroyWindow(hwnd), win32.WM_DESTROY => win32.PostQuitMessage(0), else => { stdout.print("Unknown window message: 0x{x:0>4}\n", .{uMsg}) catch undefined; }, }; return win32.DefWindowProcA(hwnd, uMsg, wParam, lParam); } pub export fn main(hInstance: win32.HINSTANCE) c_int { stdout = std.io.getStdOut().writer(); var class = std.mem.zeroes(win32.WNDCLASSEXA); class.cbSize = @sizeOf(win32.WNDCLASSEXA); class.style = win32.CS_VREDRAW | win32.CS_HREDRAW; class.hInstance = hInstance; class.lpszClassName = "Class"; class.lpfnWndProc = WindowProc; _ = win32.RegisterClassExA(&class); const hwnd = win32.CreateWindowExA(win32.WS_EX_CLIENTEDGE, "Class", "Window", win32.WS_OVERLAPPEDWINDOW, win32.CW_USEDEFAULT, win32.CW_USEDEFAULT, win32.CW_USEDEFAULT, win32.CW_USEDEFAULT, null, null, hInstance, null); _ = win32.ShowWindow(hwnd, win32.SW_NORMAL); _ = win32.UpdateWindow(hwnd); var message: win32.MSG = std.mem.zeroes(win32.MSG); while (win32.GetMessageA(&message, null, 0, 0) > 0) { _ = win32.TranslateMessage(&message); _ = win32.DispatchMessageA(&message); } return 0; }
- Tipik bir Windows uygulamasında bir
-
Yansıtma
- C makrolarını eşlemek zahmetli olabilir
- Zig'de
@typeInfofonksiyonu kullanılarak struct alanları ve bildirimleri listelenebilir - Bu sayede C makroları Zig içinde yansıtılabilir
- Örnek kod:
const window_messages = get_window_messages(); fn get_window_messages() [65536][:0]const u8 { var result: [65536][:0]const u8 = undefined; @setEvalBranchQuota(1000000); for (@typeInfo(win32).Struct.decls) |field| { if (field.name.len >= 3 and std.mem.eql(u8, field.name[0..3], "WM_")) { const value = @field(win32, field.name); result[value] = field.name; } } return result; } pub export fn WindowProc(hwnd: win32.HWND, uMsg: c_uint, wParam: win32.WPARAM, lParam: win32.LPARAM) callconv(windows.WINAPI) win32.LRESULT { _ = switch (uMsg) { win32.WM_CLOSE => win32.DestroyWindow(hwnd), win32.WM_DESTROY => win32.PostQuitMessage(0), else => { stdout.print("{s}: 0x{x:0>4}\n", .{ window_messages[uMsg], uMsg }) catch undefined; }, }; return win32.DefWindowProcA(hwnd, uMsg, wParam, lParam); }
-
Sonuç
- Zig, C'nin yapabildiği işleri daha modern programlama dili yapılarıyla daha kullanışlı biçimde gerçekleştirebilir
- Zig, C compiler toolchain'i de içererek C header dosyalarındaki bildirimleri sorunsuz biçimde dahil edebilir
- Zig'in pragmatist felsefesi, dili öğrenmeye başlar başlamaz kendini gösterir
- Zig'in sezgisel ve tutarlı tasarımı üretkenliği artırmaya katkı sağlar
GN⁺ özeti
- Zig, düşük seviye ve sistem programlamaya odaklanan yeni bir dildir ve C ile mükemmel birlikte çalışabilirlik sunar
- Zig, C header dosyalarını içe aktararak kullanabilir ve C makrolarını Zig içinde yansıtabilir
- Zig'in pragmatist felsefesi ve sezgisel tasarımı, dili öğrenmeyi ve kullanmayı büyük ölçüde kolaylaştırır
- Zig, mevcut C kod tabanlarını Zig'e taşıyacak bir yol sunarak dilin benimsenmesinin önündeki engelleri aşar
1 yorum
Hacker News görüşleri
@cImportözelliğinin kaldırılması planlanıyorlibclangbağımlılığını kaldırmak için bu özelliği dilden çıkarmak istiyorlarÖrnek kod:
D dilindeki eşdeğer kod:
Geri kalanını derleyici hallediyor
C dosyalarını içe aktarmak için özel bir sözdizimi isteyenler var, ancak bu sadelik daha iyi
Zig’i sevmek istiyorum ama birkaç sorun yaşıyorum
zig initile proje başlatmanın önerilen yolunda gereksiz çok fazla kod varzig build-exe filename.zigile başlatma kısmını atlayabildiğinizi öğrendimClang’ın önişlemcisi ayrı bir derleme öncesi aşama olarak uygulanmıyor
D dilinde ImportC kullanarak benzer bir işi nasıl yapabileceğinize dair bir blog yazdım
Her enum için çalıştırılabilir dosyaya en az
UINT16_MAX*sizeof(intptr_t)bayt eklenecek gibi görünüyorFonksiyon tanımları çok okunaklı görünüyor
Siteyi beğendim