Kotlin native callback construction

I trying to discover how to invoke Kotlin code from C in which in Kotlin a function is defined which requires a class type parameter which needs to be implemented in C.

I have a test application that should print a message to stdout using the Kotlin native C interfacing. The code consists of a Kotlin part that is compiled to a native library and C code that is compiled into an executable that uses the Kotlin native library. The implementation makes use of a callback mechanism, at startup the C code creates an instance of the library and calls an initialization function which requires a callback class parameter. Next a Kotlin native library function is called that uses the callback class to print a message to stdout. The final goal is to implement the interface definition of the callback class in C and forward it to the Kotlin native library.

Up till now I was not successful in finding the correct construct to provide the callback object to the native Kotlin library, every attempt results in a SEGFAULT. How do I use the provided structures in the generated header in C to accomplish what I’m trying to do? Or is this construct not supported yet? are there any alternative constructs that I can use? in

Kotlin Code:

hello.kt

package com.hello

class Hello {
    private var greeter: Greeter? = null

    fun initialize(greeter: Greeter) {
        this.greeter = greeter
    }

    fun sayHello(): String {
        return this.greeter?.greet() ?: "Nothing to say..."
    }

}

Greeter.kt

package com.hello

interface Greeter {
    fun greet(): String
}

Generated header libhello_api.h

#ifndef KONAN_LIBHELLO_H
#define KONAN_LIBHELLO_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
typedef bool            libhello_KBoolean;
#else
typedef _Bool           libhello_KBoolean;
#endif
typedef unsigned short     libhello_KChar;
typedef signed char        libhello_KByte;
typedef short              libhello_KShort;
typedef int                libhello_KInt;
typedef long long          libhello_KLong;
typedef unsigned char      libhello_KUByte;
typedef unsigned short     libhello_KUShort;
typedef unsigned int       libhello_KUInt;
typedef unsigned long long libhello_KULong;
typedef float              libhello_KFloat;
typedef double             libhello_KDouble;
typedef float __attribute__ ((__vector_size__ (16))) libhello_KVector128;
typedef void*              libhello_KNativePtr;
struct libhello_KType;
typedef struct libhello_KType libhello_KType;

typedef struct {
  libhello_KNativePtr pinned;
} libhello_kref_kotlin_Byte;
typedef struct {
  libhello_KNativePtr pinned;
} libhello_kref_kotlin_Short;
typedef struct {
  libhello_KNativePtr pinned;
} libhello_kref_kotlin_Int;
typedef struct {
  libhello_KNativePtr pinned;
} libhello_kref_kotlin_Long;
typedef struct {
  libhello_KNativePtr pinned;
} libhello_kref_kotlin_Float;
typedef struct {
  libhello_KNativePtr pinned;
} libhello_kref_kotlin_Double;
typedef struct {
  libhello_KNativePtr pinned;
} libhello_kref_kotlin_Char;
typedef struct {
  libhello_KNativePtr pinned;
} libhello_kref_kotlin_Boolean;
typedef struct {
  libhello_KNativePtr pinned;
} libhello_kref_kotlin_Unit;
typedef struct {
  libhello_KNativePtr pinned;
} libhello_kref_com_hello_Greeter;
typedef struct {
  libhello_KNativePtr pinned;
} libhello_kref_com_hello_Hello;

typedef struct {
  /* Service functions. */
  void (*DisposeStablePointer)(libhello_KNativePtr ptr);
  void (*DisposeString)(const char* string);
  libhello_KBoolean (*IsInstance)(libhello_KNativePtr ref, const libhello_KType* type);
  libhello_kref_kotlin_Byte (*createNullableByte)(libhello_KByte);
  libhello_kref_kotlin_Short (*createNullableShort)(libhello_KShort);
  libhello_kref_kotlin_Int (*createNullableInt)(libhello_KInt);
  libhello_kref_kotlin_Long (*createNullableLong)(libhello_KLong);
  libhello_kref_kotlin_Float (*createNullableFloat)(libhello_KFloat);
  libhello_kref_kotlin_Double (*createNullableDouble)(libhello_KDouble);
  libhello_kref_kotlin_Char (*createNullableChar)(libhello_KChar);
  libhello_kref_kotlin_Boolean (*createNullableBoolean)(libhello_KBoolean);
  libhello_kref_kotlin_Unit (*createNullableUnit)(void);

  /* User functions. */
  struct {
    struct {
      struct {
        struct {
          struct {
            libhello_KType* (*_type)(void);
            const char* (*greet)(libhello_kref_com_hello_Greeter thiz);
          } Greeter;
          struct {
            libhello_KType* (*_type)(void);
            libhello_kref_com_hello_Hello (*Hello)();
            void (*initialize)(libhello_kref_com_hello_Hello thiz, libhello_kref_com_hello_Greeter greeter);
            void (*sayHello)(libhello_kref_com_hello_Hello thiz);
          } Hello;
        } hello;
      } com;
    } root;
  } kotlin;
} libhello_ExportedSymbols;
extern libhello_ExportedSymbols* libhello_symbols(void);
#ifdef __cplusplus
}  /* extern "C" */
#endif
#endif  /* KONAN_LIBHELLO_

‘C’ Code:


#include "libhello_api.h"

const char* greet(libhello_kref_com_hello_Greeter g) {
    return "Hello from Greeter";
}


int main() {
   // Get pointer to library root object
	libhello_ExportedSymbols* lib = libhello_symbols();

    // Get the hello object (thizz)
	libhello_kref_com_hello_Hello thizz = lib->kotlin.root.com.hello.Hello.Hello();

  	libhello_kref_com_hello_Greeter greeterPtr;

    // set the greet function inside the Greeter object
    lib->kotlin.root.com.hello.Greeter.greet = greet;

    // set the pointer to the Greeter object
    greeterPtr.pinned = &lib->kotlin.root.com.hello.Greeter;

    // call the initialize function with the pointer to Greeter
	lib->kotlin.root.com.hello.Hello.initialize(thizz, greeterPtr);

    // call the sayHello function which should point to the greet() function declared above
	lib->kotlin.root.com.hello.Hello.sayHello(thizz);

    return 0;

}