High level and probably very basic question: How s...
# kotlin-native
i
High level and probably very basic question: How should K/N code handle C library initialization sanely? Say I've got some libfoo with functions
foo_init
,
foo_bar
, and
foo_baz
. Calling
foo_init
before calling
foo_bar
or
foo_baz
is mandatory (else errors occur). I can see several (bad) options: • I can add call-site guards every place I need to invoke
foo_bar
and
foo_baz
but that's boilerplate • I can eagerly call
foo_init
in some early part of my own application but that could be wasteful since I don't yet know if I'm going to invoke
foo_bar
or
foo_baz
• I can wrap access into a singleton (e.g.,
object LibFoo
) with an
init
block that performs the
foo_init
call but this requires manually binding every libfoo API into a singleton method What am I missing? What are other people doing?
s
Hard to know the best approach without more context, but with a similar problem in the past I did something like: make all my functions that need to invoke foo_bar or foo_baz take an extra parameter. This parameter is of a type that can only be constructed by calling my function that invokes foo_init. So the caller needs this "token" value which they get returned from my init wrapper
l
I don't think there is a single answer. In fact, there is really nothing unique to Kotlin in this case. You'd have exactly the same issue in C.
Now the question may be rephrased as: Are there any features of Kotlin that allows you to make this more reliable than if you had used C? I can't really think of anything would significantly help here.
i
True this is not necessarily a "Kotlin problem" but I am hoping for a "Kotlin solution". 😊 Some additional context I can provide is that the library I'm binding exports hundreds of functions—more than I want to manually wrap. My invocations of these functions will be spread throughout my own code—more than I want to manually guard. Kotlin's C interop nicely presents a library's exports as top-level free functions and what I find myself wanting is just a bit more—for everything but the initialization function to be presented as a method on a singleton, the
init { }
for which calls the C library's initializer. I'm not stuck on that as a solution but it's closer to how I would write "real" Kotlin code that needed to enforce certain constraints at runtime such as bootstrapping.
l
When are
init
methods on
object
instances called in Kotlin native? In Java they're only called when the class is loaded, but Kotlin native calls them at startup?
k
If I were you I’d create a
Foo
class that exposes
bar
and
baz
functions. When that class is constructed ensure
foo_init
was called. To avoid multiple calls to
foo_init
you could wrap it in some lazy initializer that only fires upon first request and is internal to your library.
i
Yeah that's kind of the third bullet I listed above. That would work for my toy example but, as I mentioned later, there are hundreds of functions to bind. I'd rather not write all of those wrapping methods by hand.
🤔 Although I wonder if I could use KSP to generate a class or singleton based on the generated bindings...