Bindings with C Bit Fields

I’m currently writing some bindings for libpipewire for an application I’m working on and need to access some data that is stored in the following C struct:

struct pw_proxy {
	struct spa_interface impl;	/**< object implementation */

	struct pw_core *core;		/**< the owner core of this proxy */

	uint32_t id;			/**< client side id */
	const char *type;		/**< type of the interface */
	uint32_t version;		/**< client side version */
	uint32_t bound_id;		/**< global id we are bound to */
	int refcount;
	unsigned int zombie:1;		/**< proxy is removed locally and waiting to
					  *  be removed from server */
	unsigned int removed:1;		/**< proxy was removed from server */
	unsigned int destroyed:1;	/**< proxy was destroyed by client */
	unsigned int in_map:1;		/**< proxy is in core object map */

	struct spa_hook_list listener_list;
	struct spa_hook_list object_listener_list;

	const struct pw_protocol_marshal *marshal;	/**< protocol specific marshal functions */

	void *user_data;		/**< extra user data */
};

I ended up with the following on the Odin side:

proxy :: struct {
	impl:                 spa_interface,
	core:                 ^core,
	id:                   u32,
	type:                 cstring,
	version:              u32,
	bound_id:             u32,
	refcount:             c.int,
	// status:               bit_field u8 {
	// 	zombie:    uint | 1,
	// 	removed:   uint | 1,
	// 	destroyed: uint | 1,
	// 	in_map:    uint | 1,
	// },
	listener_list:        spa_hook_list,
	object_listener_list: spa_hook_list,
	marshal:              rawptr, // const struct protocol_marshal *marshal
	user_data:            rawptr,
}

but had to comment out all of the status bits to make the struct match in size. Is there a known way to bind so something like this or do I just have to make due without that info since the size and layout of those fields are undefined?

I’d be concerned about where that extra data went. The fact that it only lines up without the bitfield implies that something else isn’t right, at least to me. Have you checked the offsets of the individual fields (and sizes of the other structs) to make sure they’re correct?

As far as actually being able to use the bitfield: it’s OS-specific, so you don’t need to worry about it working on a wide variety of compilers. As long as the Odin representation matches what the corresponding shared library uses, you shouldn’t have any problems. It should be stable, otherwise it would break any other code that depended on those fields.

1 Like

Yeah, that’s probably a good idea. The reason it hasn’t crashed yet is probably because I’m not using those later fields. I’ll definitely give it a closer look tho