#Field access on C opaque types

1 messages · Page 1 of 1 (latest)

novel lintel
#

I'm trying to implement some functions for GTK4 custom types in Zig, due to Zig being unable to translate the gtk.h macros:

// src/demowidget.h
#pragma once
#include <gtk/gtk.h>
#define DEMO_TYPE_WIDGET demo_widget_get_type()
G_DECLARE_FINAL_TYPE(DemoWidget, demo_widget, DEMO, WIDGET, GtkWidget)
GtkWidget *demo_widget_new(void);

// src/demowidget.c
#include "demowidget.h"
struct _DemoWidget {
  GtkWidget parent_instance;
  GtkWidget *button;
};
G_DEFINE_TYPE(DemoWidget, demo_widget, GTK_TYPE_WIDGET)
GtkWidget *demo_widget_new(void) {
  return g_object_new(DEMO_TYPE_WIDGET, NULL);
}

// src/demowidget.zig
const c = @cImport(@cInclude("demowidget.h"));
// ...
export fn demo_widget_init(self: *c.DemoWidget) void {
    const widget = ptrCastAlign(*c.GtkWidget, self);
    self.button = c.gtk_button_new_with_label("Hello, world!");
}
// ...

This gives the following error: src/demowidget.zig:9:9: error: type '*.home.ubuntu.work.zig-debug.zig-cache.o.1cd51e0688c994fa4839928440c40ab8.cimport.struct__DemoWidget' does not support field access self.button = c.gtk_button_new_with_label("Hello, world!");

Is there a way to access fields in Zig for opaque types? G_DEFINE_TYPE() basically expands to typedef _DemoWidget DemoWidget; among other things like the demo_widget_init() function declaration.

#

To test things out I made the following mini-demo:

// test.h
typedef struct _Demo Demo;
Demo *d_new();
void d_free(Demo *ptr);

// test.c
#include "stdlib.h"
#include "test.h"

struct _Demo {
  int a;
};

Demo *d_new() { return (Demo *)malloc(sizeof(Demo)); }
void d_free(Demo *ptr) { free(ptr); }

// test.zig
const std = @import("std");
const c = @cImport(@cInclude("test.h"));

pub fn main() void {
    const d = c.d_new().?;
    defer c.d_free(d);

    d.*.a = 3;

    std.debug.print("{}\n", .{d.*.a});
}

where:

~/work/zig-debug> zig run test.zig test.c -I. -lc                                                                                                     2 06/15/2023 09:52:53 AM
test.zig:8:6: error: values of type '.home.ubuntu..cache.zig.o.d5057e1e6584692f1d4f93b3984ced55.cimport.struct__Demo' must be comptime-known, but operand value is runtime-known
    d.*.a = 3;
    ~^~
test.zig:8:6: note: opaque type '.home.ubuntu..cache.zig.o.d5057e1e6584692f1d4f93b3984ced55.cimport.struct__Demo' has undefined size
referenced by:
    comptime_0: /home/ubuntu/applications/bin/lib/std/start.zig:63:50
    remaining reference traces hidden; use '-freference-trace' to see all reference traces
#

I think I realized... I need to make setter/getter functions in C, don't I?

tribal haven
#

why isn't your struct in your header file ?

novel lintel
#

Cause that's how GTK4 macros work

tribal haven
#

it works for me

tribal haven
#

with the .h the zig code doesn't know about the struct field neither about the function body

novel lintel
#

Ah... I didn't know you can import c

tribal haven
#

does it help ?

novel lintel
#

I'm trying to figure out how to compile it now (with c), but I think so :)

#

O yea, simple, you don't have to include the *.h, *.c files on the zig run call, nice

#

Thanks

tribal haven
#

you're welcome ^^

novel lintel
#

Now I just have to figure out all of the other pointer-cast errors :))

tribal haven
#

I don't know much about that xD

#

good luck xD