Right now I am trying to export out some test code using export
.
pub const RL_AudioStream = Resource(raylib.AudioStream);
pub const RL_AudioStreamTrait = ResourceTrait(RL_AudioStream);
pub const ResourceManagerForAudioStream = ResourceManager(RL_AudioStream, RL_AudioStreamTrait);
pub const ResourceManagerWrapperForAudioStream = ResourceManagerWrapper(RL_AudioStream, RL_AudioStreamTrait);
pub export fn AudioStreamManager_Init_GPA() ?*ResourceManagerWrapperForAudioStream {
return ResourceManager_Init_GPA(RL_AudioStream, RL_AudioStreamTrait);
}
And this works great. However I have 30 types I need to do this for. So I wanted to loop over some values to do this for me in Zig. So I was hoping comptime and a loop would be possible. Here is the code which does not work.
const Types = .{
.{ "AudioStream", raylib.AudioStream },
.{ "Vector3", raylib.Vector3 },
.{ "Mesh", raylib.Mesh },
};
const CreateGpaType = struct {
const Self = @This();
typeName: []const u8,
resourceType: type,
trait: type,
fn call(self: *Self) ?*anyopaque {
const result = ResourceManager_Init_GPA(self.resourceType, self.trait);
if (result) |wrapper| {
return @as(*anyopaque, @ptrCast(wrapper));
} else {
return null;
}
}
};
comptime {
for (Types) |typeInfo| {
const TypeName = typeInfo[0];
const ResourceType = typeInfo[1];
const rlType = Resource(ResourceType);
const rlTypeTrait = ResourceTrait(rlType);
const createGpa = CreateGpaType{
.typeName = TypeName,
.resourceType = rlType,
.trait = rlTypeTrait,
};
const symbol_name = "Manager_Init_GPA_" ++ TypeName;
@export(@as(*CreateGpaType, @constCast(&createGpa)).call, .{ .name = symbol_name, .linkage = .strong });
}
}
Obviously you cannot reference the .call
I also tried exporting the struct:
@export(createGpa, .{ .name = symbol_name, .linkage = .strong });
But you cannot export structs, unless marked with extern but you cannot export structs with comptime types i.e:
const CreateGpaType = extern struct {
const Self = @This();
typeName: [64]u8,
resourceType: type,
trait: type,
fn call(self: *Self) ?*anyopaque {
const result = ResourceManager_Init_GPA(self.resourceType, self.trait);
if (result) |wrapper| {
return @as(*anyopaque, @ptrCast(wrapper));
} else {
return null;
}
}
};
error: extern structs cannot contain fields of type 'type'
resourceType: type,
^~~~
If I try exporting the wrapped struct , which will not work inside a for loop:
fn exportedWrapper() callconv(.C) *anyopaque {
const result = @as(*CreateGpaType, @constCast(&createGpa)).call();
return result orelse @panic("exportedWrapper: null returned where *anyopaque is expected");
}
comptime {
@export(exportedWrapper, .{ .name = symbol_name, .linkage = .strong });
}
I can wrap the struct inside a function to be returned, then in C I can call Manager_Init_GPA_AudioStream()
, unravel void*
into a struct, which I would need to redeclare in C since Zig will not export that information out due to *anyopaque
, which is needed since comptime types cannot be exported.
fn exportedWrapper() callconv(.C) *anyopaque {
const result = @as(*CreateGpaType, @constCast(&createGpa));
return result;
}
comptime {
@export(exportedWrapper, .{ .name = symbol_name, .linkage = .strong });
}
But then it goes back, I wanted to use this inside a for loop
and functions cannot be defined inside a for loop…
Any thoughts?