Hello all,
I’m interested in creating a multi-lingual project with a Julia backend. I’d like to do this through a C ABI layer and would like advice on how to structure it.
Since my usecase is a bit difficult to explain, I’ve likened it to a basic video game. Here’s my current idea of how to structure it:
Julia has a world struct and some way to update the world:
module Game
mutable struct World
playerx :: Float32
playery :: Float32
playerhealth :: Int
end
function step!(w::World, ...)
...
end
end #module
It has a function callable from C that creates a World and returns a pointer:
module CLayer
const _registry = Dict{UInt, Base.RefValue{Model}}()
Base.@ccallable function create_world(...) :: Ptr{Nothing}
w = Game.World(...)
r = Ref(w)
p = UInt(pointer_from_objref(r))
_registry[p] = r
return Ptr{Nothing}(p)
end
end #module
Module CLayer also has a function callable from C that updates the world:
Base.@ccallable function step(ptr::Ptr{Nothing}, ...) :: Cvoid
w = _ref(ptr)
Game.step!(w[], ...)
unsafe_copyo!(ptr, pointer(encode(w), length(w))
nothing
end
I could then compile that with
using PackageCompiler
create_library(
\"$IN_DIR\",
\"$OUT_DIR\";
lib_name = \"game\",
incremental = false,
filter_stdlibs = false,
force = true,
)
Then, I would have a header file that looked something like this:
#include <stdint.h>
void* create_world(...);
void step(void* world, ...);
I think this should allow for other languages to then implement these C methods. I’ve heard of a similar approach being used for plugins, but I think that would require Julia code also calling C code.
I was wondering what others thought of this approach. Do you think it will scale? Is it performant? Is there a bug somewhere?
Please excuse the many beginner mistakes I’m sure I have made in this post – this is definitely not my forte.