Help with abi (opaque)(struct)

ABI woes

Context

So I’m just making dev tooling at work for fun to play with zig.

Context for the job is we have a cpp interface that is passing messages around. So I spent the afternoon making c_bindings for some of the interfaces and got that all hooked up quite nicely.

So I’m currently right here,

pub const struct_proprietary_cool_name = opaque {};
pub const proprietary_cool_name = struct_proprietary_cool_name;
pub extern fn create_proprietary_cool_name(...) ?*proprietary_cool_name;
pub extern fn destroy_proprietary_cool_name(obj: ?*proprietary_cool_name) void;
pub extern fn connect_to_proprietary_cool_name(obj: ?*proprietary_cool_name, process_name: [*c]const u8) void;
pub extern fn subscribe_to_uri_array(obj: ?*proprietary_cool_name, uri_array: [*c][*c]const u8, count: c_int) void;
pub extern fn receive_message_from_proprietary_cool_name(obj: ?*proprietary_cool_name) void;

Problem

So this is great I can call all these functions and they work.

But now I need to access some of the values inside struct_proprietary_cool_name.
But it’s opaque.

Is there anyway to just do this? Or do I have to make a c function get_field and then pass the cool_name* to another c function?

It would be cool if I can just receive a class pointer and scamper away into zig.

Secret Sauce

Look how cool.

const std = @import("std");
const cool_name = @import("cool_name.zig");
pub fn main() !void {
    const pcool_name = cool_name.create_cool_name();
    defer cool_name.destroy_cool_name(pcool_name);
    if (pcool_name != null) {
        cool_name.connect_to_cool_name(pcool_name, "ziggin");
    }
    // subscribe to the following uri
    const uris = [1:0][*c]const u8{"/site"};
   cool_name.subscribe_to_uri_array(pcool_name, @constCast(&uris), 1);
   while (true) {
        const msg = cool_name.receive_message_from_cool_name(pcool_name);
        if (msg != null) {
            std.debug.print("recieving", .{});
         }
     }
 }

I believe you have to either declare your opaque as an actual extern struct or @ptrCast the opaque to an actual struct type. You maybe could use cImport with some header file to get a auto translated zig definition for the struct.

If the line:

pub const struct_proprietary_cool_name = opaque {};

Was created by a cImport, I think it would possibly expand into an actually defined struct if you add another header file that contains the definition of the type.
Some c files only contain forward declarations telling zig nothing about what the actual type is, so those get defined as opaque, which are essentially unknown blobs.

Defining a function that returns the field is another way to do it, but you need to weigh what makes more sense, if the type is very complex and can’t be auto imported, an explicit accessor function might be easier, however if it can be imported that might save you from creating a lot of unnecessary accessor and setter functions.

I don’t have that much experience with c-translate / cImport, so I don’t know exact details about what works well.