napperley
11/08/2022, 2:28 AMnapperley
11/08/2022, 2:30 AM// IntelliJ API Decompiler stub source generated from a class file
// Implementation of methods is not available
package io.gitlab.embedSoft.lvglKt.core.clib.lvgl
@kotlinx.cinterop.internal.CStruct public final class lv_mem_monitor_t public constructor(rawPtr: kotlinx.cinterop.NativePtr /* = kotlin.native.internal.NativePtr */) : kotlinx.cinterop.CStructVar {
@kotlinx.cinterop.internal.CStruct.VarType @kotlin.Deprecated public companion object : kotlinx.cinterop.CStructVar.Type {
}
public final var frag_pct: platform.posix.uint8_t /* = kotlin.UByte */ /* compiled code */
public final var free_biggest_size: platform.posix.uint32_t /* = kotlin.UInt */ /* compiled code */
public final var free_cnt: platform.posix.uint32_t /* = kotlin.UInt */ /* compiled code */
public final var free_size: platform.posix.uint32_t /* = kotlin.UInt */ /* compiled code */
public final var max_used: platform.posix.uint32_t /* = kotlin.UInt */ /* compiled code */
public final var total_size: platform.posix.uint32_t /* = kotlin.UInt */ /* compiled code */
public final var used_cnt: platform.posix.uint32_t /* = kotlin.UInt */ /* compiled code */
public final var used_pct: platform.posix.uint8_t /* = kotlin.UByte */ /* compiled code */
}
public final class lv_mem_buf_t public constructor(rawPtr: kotlinx.cinterop.NativePtr /* = kotlin.native.internal.NativePtr */) : kotlinx.cinterop.CStructVar {
@kotlinx.cinterop.internal.CStruct.VarType @kotlin.Deprecated public companion object : kotlinx.cinterop.CStructVar.Type {
}
public final var p: kotlinx.cinterop.COpaquePointer? /* = kotlinx.cinterop.CPointer<out kotlinx.cinterop.CPointed>? */ /* compiled code */
public final var size: platform.posix.uint16_t /* = kotlin.UShort */ /* compiled code */
public final var used: platform.posix.uint8_t /* = kotlin.UByte */ /* compiled code */
}
Pavel Kunyavskiy [JB]
11/08/2022, 3:03 AMnapperley
11/08/2022, 3:04 AMPavel Kunyavskiy [JB]
11/08/2022, 3:07 AMnapperley
11/08/2022, 3:08 AMnapperley
11/08/2022, 3:09 AMe5l
11/08/2022, 4:19 AMsvyatoslav.scherbina
11/08/2022, 9:00 AMWho should I be contacting?Support engineer is not a person who can answer all these questions. Please don’t tag anyone. As Pavel said, that reduces the chance that someone else will help you.
Is there some hidden documentation on the knm file format?No hidden documentation, please use the source code, it is open.
What is the current status on the knm file format?It is supported by the compiler and various tools.
Will the knm file format continue to exist?No guarantees, likely yes.
How will the knm files work in their final form?The files don’t “work”, they can be emitted or parsed. Your question is unclear.
What is being done to remove the messy comments that make the file format very verbose/noisy (impossible to parse)?There are no messy comments in the knm file format.
Below is an example of what a knm file looks like in its current form (trimmed for brevity):That’s not true. knm is a binary format, what you show is an output of a tool that can parse knm format and dump it in a human-readable form. Please create a YouTrack issue if you have problems with it or would like to request a feature.
Is the knm file format being positioned for use in code generation (eg to create Kotlin bindings for a C library)?The knm file format is used as an implementation detail of klibs, and
cinterop
tool in particular. Not sure what you mean by positioning, but klibs produced by cinterop
can be read by the compiler, including its current and likely next versions.
Will there be an official Kotlin library (You can try to use this library: https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-metadata-klib/ It is experimental, no guarantees.) provided to aid in extracting meta data from knm files (eg for use in creating Kotlin bindings for a C library)?@e5l
(eg for use in creating Kotlin bindings for a C library)?Why would you need this, if you have
cinterop
?napperley
11/09/2022, 4:15 AMWhy would you need this, if you haveWhen getting a wrapper generated for a C library the cinterop tool works fine, but isn't sufficient for bindings, which need to provide proper Kotlin APIs instead of C like APIs.?cinterop
You can try to use this library: https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-metadata-klib/Is there an example of using the KotlinX Metadata Klib library (aka, sample project)?
No hidden documentation, please use the source code, it is open.Is there a good starting point in the source code for reference documentation that introduces the knm file format?
svyatoslav.scherbina
11/09/2022, 10:53 AMWhen getting a wrapper generated for a C library the cinterop tool works fine, but isn’t sufficient for bindings, which need to provide proper Kotlin APIs instead of C like APIs.Why not write these Kotlin APIs in Kotlin then? You can’t actually generate Kotlin wrappers as .knm, because .knm doesn’t contain function bodies.
Is there an example of using the KotlinX Metadata Klib library (aka, sample project)?No.
Is there a good starting point in the source code for reference documentation that introduces the knm file format?https://github.com/JetBrains/kotlin
git grep -r knm
napperley
11/09/2022, 10:54 PMnapperley
11/10/2022, 12:03 AM// ...
static void event_handler(lv_event_t * e)
{
lv_event_code_t code = lv_event_get_code(e);
if(code == LV_EVENT_CLICKED) {
LV_LOG_USER("Clicked");
}
else if(code == LV_EVENT_VALUE_CHANGED) {
LV_LOG_USER("Toggled");
}
}
void lv_example_btn_1(void)
{
lv_obj_t * label;
lv_obj_t * btn1 = lv_btn_create(lv_scr_act());
lv_obj_add_event_cb(btn1, event_handler, LV_EVENT_ALL, NULL);
lv_obj_align(btn1, LV_ALIGN_CENTER, 0, -40);
label = lv_label_create(btn1);
lv_label_set_text(label, "Button");
lv_obj_center(label);
lv_obj_t * btn2 = lv_btn_create(lv_scr_act());
lv_obj_add_event_cb(btn2, event_handler, LV_EVENT_ALL, NULL);
lv_obj_align(btn2, LV_ALIGN_CENTER, 0, 40);
lv_obj_add_flag(btn2, LV_OBJ_FLAG_CHECKABLE);
lv_obj_set_height(btn2, LV_SIZE_CONTENT);
label = lv_label_create(btn2);
lv_label_set_text(label, "Toggle");
lv_obj_center(label);
}
Below is the Kotlin snippet using the hypothetical Kotlin bindings for the LVGL library:
// ...
fun eventHandler(evt: Event) {
val code = evt.code
if (code == EventType.CLICKED) logUser("Clicked")
else if (code == EventType.VALUE_CHANGED) logUser("Toggled")
}
fun lvExampleBtn1() {
val btn1 = button(actualScreen()) {
addEventCallback(::eventHandler, EventType.ALL)
alignObject(alignType = AlignmentType.CENTER, xPos = 0,
yPos = -40)
}
label(btn1) {
text = "Button"
centerObject()
}
val btn2 = button(actualScreen()) {
addEventCallback(::eventHandler, EventType.ALL)
alignObject(alignType = AlignmentType.CENTER, xPos = 0,
yPos = 40)
addFlag(ObjectFlag.CHECKABLE)
height = SIZE_CONTENT
}
label(btn2) {
text = "Toggle"
centerObject()
}
}
svyatoslav.scherbina
11/10/2022, 9:01 AMactualScreen
should call lv_scr_act
? That’s what function bodies are required for.napperley
11/10/2022, 11:48 PMlv_scr_act
(in the LVGL documentation the lv_scr_act
function is used to get the active screen of the default display - https://docs.lvgl.io/latest/en/html/overview/display.html?highlight=lv_scr_act#_CPPv410lv_scr_actv ) can't be used since it doesn't fit into the Kotlin Coding Conventions with the naming (also uses ambiguous abbreviations), hence the name actualScreen
is used (should have been renamed to activeScreen
) for the function name instead. Since cases like this will crop up from time to time, there will need to be a facility in the code generation system (for creating the bindings) to do manual overrides. There is no such thing as perfect code generation. Many code generation runs, and examination/tweaking of the results will need to be done , before ending up a good result that is idiomatic Kotlin and provides a decent develop experience for the user with the API ergonomics.
One cannot expect the code generation to pick up everything that is needed to generate usable bindings for a library. There will be a few places where manual overrides are needed. Often key stuff like memory management with APIs are picked up through library documentation, unless the library has a meta data system that can be used to collect this data by symbol lookup.svyatoslav.scherbina
11/11/2022, 9:10 AMlv_scr_act
you can simply change the function name, but this won’t work for cases like addEventCallback
, where you need to have a wrapper with non-trivial logic inside. Otherwise the compiler just doesn’t know how to translate addEventCallback(::eventHandler, EventType.ALL)
into lv_obj_add_event_cb(this, staticCFunction(::eventHandler), EventType.ALL, null)
Alternatively, you can do this without generating Kotlin code with the help of a compiler plugin.napperley
11/11/2022, 9:18 PMnapperley
11/11/2022, 9:23 PMsvyatoslav.scherbina
11/14/2022, 8:58 AMAre you suggesting that there are certain parts of the code generation that would be better covered with a compiler plugin?No, I’m just saying that you can usually make a compiler plugin that generates wrappers instead of writing these wrappers manually.
Are Kotlin compiler plugins suitable for cases where Kotlin bindings need to be generated for a C library?For some parts of the process, maybe.