How to convert from main function args: Array<String> to C type main function argc, char **argv?

I am trying to use C GUI library with kotlin/native (win 10 pro / x64). Got some progress, but main initialization function of that toolkit library expect parameters exactly the same as one defined for regular C application main function i.e.: (int argc, char **argv).

How do I convert kotlin main function parameters args: Array to C int argc, char **argv
equivalent ?

I’ve was unable to find usable solution so far.

I don’t really have much experience with native, but from what i can tell and based on https://kotlinlang.org/docs/reference/native/c_interop.html#passing-pointers-to-bindings I came up with this:

fun main(args: Array<String>) {
    val argc = args.count
    val argv = args.map { 
        it.cstr.getPointer(nativeHeap)
    }.toCValues()
}

Then you can just call the c function, assuming you have the necessary bindings already.

Wasabi375, thank you for suggested code. I’ve tried it, but unfortunatly got following issues:

  1. For args.count statement I’ve got error: function invocation ‘count()’ expected

  2. For it.cstr.getPointer(nativeHeap) statement: error: type mismatch: inferred type is nativeHeap but AutofreeScope was expected

Wooops, I always mix up size and count(). Both work, they are pretty much the same.

As I said, I don’t have much experience with native and even less with C interop. That said, the code should work if you wrap it in a memScoped block.
https://kotlinlang.org/docs/reference/native/c_interop.html#memory-allocation

Hi, @agb1! Unfortunately, the documentation on C Interop can be misleading sometimes, some parts of it are slightly outdated. For now, there are two main ways you can send a string to a C function:

  1. allocating the memory inside of a memScoped block, as @Wasabi375 suggested, or
  2. instantiating an instance of Arena class, using it to allocate memory like this:
val ar = Arena()
val ref = "Hello".cstr.getPointer(ar)
...
ar.clear() // wipes all the memory allocated on the arena before

The main difference here will be the lifetime of the allocated object. The first approach guarantees that the memory won’t be cleaned till the end of the block. So, if you want this pointer to be fine for all program’s lifetime, it can be a bad idea to wrap all main() lines into a one big memScoped block. On the other side, memScoped is a lot easier to use as there is no need to clear it manually. For a quick sending something to the C side, it fits much better IMHO.

Hello @Wasabi375 ! Thanks again for your comments on the subject of this message - they were usefull !

Hi, @Artyom.Degtyarev ! Thank you for providing additional information. I would try both solutions to see what would be the best one to apply in my code. Could you please advice - what’s the best place to look for up to date docs regarding kotlin/native ? Would it be github project page and source code ? Also for cases like one I mentioned it would be greate if some kind on demo source code or just parts of code could be provided (I mean short complete application demonstrating usage and probable with comments regarding what are the requirements and restrictions for that solution).
Thank you for your suggestion !

About the documentation - we’re trying to keep the doc up-to-date, this particular mistake should be solved soon. Website kotlinlang.org is the most reliable source of documentation for now. I would also recommend you to check things on a stdlib reference, it is guaranteed to be up-to-date with the latest release.
Some useful examples can be found across K/N GitHub repo, in the /samples/ directory. There is a couple of examples could be interesting for you. Also, there is a kotlin-libui project with similar goals if I understand you correctly. Maybe looking through it can help you.