Cyrille QUÉMIN
08/08/2019, 11:20 PMinterface View{
suspend fun myFunSuspend().
}
// for Android, normal implementation of co routine
// for iOS see below, because I need to call a function in swift that uses callbacks
class iOSViewWrapper(private val iOSImpl: IosView) : View {
override suspend fun myFunSuspend(){
return suspendCoroutine {
iOSImpl.doAsyncJob{ data, error ->
if(error != null){
it.resumeWithException(error)
}else{
it.resume(data)
}
}
}
}
}
interface IosView {
fun doAsyncJob((data: ByteArray, error: Throwable?)-> Unit)
}
the function doAsyncJob
implementation is done in Swift and is called many times inside my kotlin code.
I have defined a coroutine scope that is using the ios dispatch_get_main_queue
.
I have made sure that doAsyncJob
is execute AND invoke the closure on the main thread.
The code works but crashes always in the swift invocation of the closure.
Sometimes after 1 call sometimes after 6 or 10, ...
I tried to declare the closure of doAsyncJob
as a variable and call .freeze()
on it, but I get
kotlinx.coroutines.CoroutinesInternalError: Fatal exception in coroutines machinery for DispatchedContinuation[MainDispatcher@7d793018, Continuation @ $prepareCOROUTINE$11]. Please read KDoc to 'handleFatalException' method and report this incident to maintainers
at 0 mylib 0x0000000100f81e98 kfun:kotlin.Error.<init>(kotlin.String?;kotlin.Throwable?)kotlin.Error + 24
at 1 mylib 0x0000000100f81bc0 kfun:kotlinx.coroutines.CoroutinesInternalError.<init>(kotlin.String;kotlin.Throwable)kotlinx.coroutines.CoroutinesInternalError + 24
at 2 mylib 0x0000000100f81818 kfun:kotlinx.coroutines.DispatchedTask.handleFatalException$kotlinx-coroutines-core(kotlin.Throwable?;kotlin.Throwable?) + 284
at 3 mylib 0x0000000100f82540 kfun:kotlinx.coroutines.DispatchedTask.run() + 1224
what am I doing wrong?
I am using kotlin 1.3.41
and coroutine 1.3.0-RC
with an mpp project android and ioslouiscad
08/09/2019, 7:09 AMNabil
08/09/2019, 8:44 AMLong
so it can be passed later to make some invocations via the C-interop (the Long
value is reinterpret_cast<CppObj*>(pointer)
to whatever the original C/C++ object is), usually we want to deallocate explicitly this pointer when the object get GC’ed via the reference counter.
I’m aware of the existing memory management approaches (memScope/arena etc.) but in this scenario we can not wrap every instance of the Kotlin class inside a memScope/arena, these are instances passed to the user of the API so we don’t control their lifecycles, this is why deallocating the C++ resources should be tied to the collection of the original Kotlin instance (to draw a parallel, this is the pattern used in Java with Phantom reference & a referenceQueue to close native pointers, see CrazyBob presentation https://www.youtube.com/watch?v=KTC0g14ImPc)▾
Yan Pujante
08/09/2019, 3:18 PMlibnative_kref_example_Clazz newInstance = lib->kotlin.root.example.Clazz.Clazz();
long x = lib->kotlin.root.example.Clazz.memberFunction(newInstance, 42);
lib->DisposeStablePointer(newInstance.pinned);
What happens if instead I have the following Kotlin code:
interface Foo {}
private class FooImpl : Foo {}
createFoo() : Foo { return FooImpl() }
and I call createFoo
from C++ (in other words, the object is created on the Kotlin side not the C++ side). How do I tell the Kotlin side that I am going to keep the Foo
instance for a while? Does it work the same and I am supposed to call DisposeStablePointer
when I am done?Jeremy
08/11/2019, 4:04 AMMarko Mitic
08/11/2019, 3:08 PMSam
08/12/2019, 9:36 PMfcosta
08/13/2019, 12:08 AMFilippo Pizzicola
08/13/2019, 2:02 PMSBNTT
08/13/2019, 4:10 PMpandawarrior
08/14/2019, 10:09 AM/Users/teamcity/buildAgent/work/4d622a065c544371/runtime/src/main/cpp/Memory.cpp:770: runtime assert: Must be positive
. I am currently looking at https://github.com/JetBrains/kotlin-native/blob/v1.3.1/runtime/src/main/cpp/Memory.cpp#L770 for clues. Anyone has any ideas how to go about this?Andrei Marshalov
08/16/2019, 8:40 AMCloseable
interface and copied use
extension from <http://kotlin.io|kotlin.io>
package. It looks like:
interface Closeable {
fun close()
}
@Throws(Throwable::class)
inline fun <T : Closeable?, R> T.use(block: (T) -> R): R {
var exception: Throwable? = null
try {
return block(this)
} catch (e: Throwable) {
exception = e
throw e
} finally {
when {
this == null -> {}
exception == null -> close()
else ->
try {
close()
} catch (closeException: Throwable) {
// cause.addSuppressed(closeException) // ignored here
}
}
}
}
It works fine for android, but in Swift i have some problem. Function signature from xCode: UtilitiesKt.use(receiver: Closeable?, block: (Closeable?) -> Any?, result: AutoreleasingUnsafeMutablePointer<AnyObject??)
use
function in xCode marked as trowable
, due to @Throws(Throwable::class)
annotation, but if i try use trowable
functions in block
lambda, xCode says: Invalid conversion from throwing function of type '(Closeable?) throws -> Any?' to non-throwing function type '(Closeable?) -> Any?'
Maybe someone know, how can i mark lambda parameter as throwable
in kotlin?gmaciel
08/18/2019, 8:32 PM@Throws
annotation in a commonMain
module? The IDE doesn't find and i'm using kotlin 1.3.41napperley
08/19/2019, 7:15 AMsalomonbrys
08/19/2019, 9:29 AMkpgalligan
08/19/2019, 3:38 PMType mismatch: inferred type is Long but NSInteger /* = Int */ was expected
elect
08/21/2019, 9:51 AMSlackbot
08/22/2019, 6:09 AMKris Wong
08/22/2019, 3:38 PMivan.savytskyi
08/22/2019, 3:39 PMoverride fun foo(): CPointer<ByteVar>?
, should I use StableRef
like:
override fun foo(): CPointer<ByteVar>? {
return StableRef
.create(name.encodeToByteArray())
.asCPointer()
.rawValue
.let { interpretCPointer(it) }
}
tapchicoma
08/22/2019, 7:40 PMThis release brings more pre-imported Apple frameworks for all platforms, including macOS and iOS.Is there any list of this additional frameworks? Or they all listed here: https://github.com/JetBrains/kotlin-native/tree/master/platformLibs/src/platform/ios?
ivan.savytskyi
08/22/2019, 7:59 PMclass MyFooModule : NSObject(), FooModuleProtocol {
. But this information is erased @interface MyFooModule : KotlinBase
in the result generated header file. How to make header file to look like this @interface MyFooModule : KotlinBase <FooModule>
?Dominaezzz
08/22/2019, 9:44 PMmsink
08/22/2019, 9:54 PMenableFeaturePreview("GRADLE_METADATA")
on consumer side can be removed with 1.3.50 and Gradle 5.6Sam
08/23/2019, 5:08 AMYan Pujante
08/23/2019, 2:44 PMerror: Invalid value (Producer: 'LLVM6.0.1' Reader: 'LLVM APPLE_1_900.0.39.2_0')
1 error generated.
e: Compilation failed: The /Applications/Xcode9.2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ command returned non-zero exit code: 1.
output:
* Source files: SampleMacos.kt, PlatformView.kt
* Compiler version info: Konan: 1.3.50 / Kotlin: 1.3.50
* Output kind: STATIC
e: org.jetbrains.kotlin.konan.KonanExternalToolFailure: The /Applications/Xcode9.2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ command returned non-zero exit code: 1.
> Process 'command '/local/sdkman/candidates/java/8.0.212-zulu/bin/java'' finished with non-zero exit value 2
Just an FYI if you plan to migrate...cubesky
08/23/2019, 3:57 PMnapperley
08/25/2019, 2:06 AMtype Nothing? is not supported here: doesn't correspond to any C type
Double checked the mapping (in the knm file) and found that the return type is CPointer<gtk3.GtkWidget>?
for the function (gtk_file_chooser_dialog_new
) that is called in the program. However the function definition looks very odd:
@kotlinx.cinterop.internal.CCall public external fun gtk_file_chooser_dialog_new(@kotlinx.cinterop.internal.CCall.CString title: kotlin.String?, parent: kotlinx.cinterop.CValuesRef<gtk3.GtkWindow /* = gtk3._GtkWindow */>?, action: gtk3.GtkFileChooserAction, @kotlinx.cinterop.internal.CCall.CString first_button_text: kotlin.String?, vararg variadicArguments: kotlin.Any?): kotlinx.cinterop.CPointer<gtk3.GtkWidget /* = gtk3._GtkWidget */>? { /* compiled code */ }
napperley
08/25/2019, 4:14 AMpublic fun udev_list_entry_get_by_name(list_entry: kotlinx.cinterop.CValuesRef<cnames.structs.udev_list_entry>?, @kotlinx.cinterop.internal.CCall.CString name: kotlin.String?): kotlinx.cinterop.CPointer<cnames.structs.udev_list_entry>? { /* compiled code */ }
public fun udev_list_entry_get_name(list_entry: kotlinx.cinterop.CValuesRef<cnames.structs.udev_list_entry>?): kotlinx.cinterop.CPointer<kotlinx.cinterop.ByteVar /* = kotlinx.cinterop.ByteVarOf<kotlin.Byte> */>? { /* compiled code */ }
public fun udev_list_entry_get_next(list_entry: kotlinx.cinterop.CValuesRef<cnames.structs.udev_list_entry>?): kotlinx.cinterop.CPointer<cnames.structs.udev_list_entry>? { /* compiled code */ }
public fun udev_list_entry_get_value(list_entry: kotlinx.cinterop.CValuesRef<cnames.structs.udev_list_entry>?): kotlinx.cinterop.CPointer<kotlinx.cinterop.ByteVar /* = kotlinx.cinterop.ByteVarOf<kotlin.Byte> */>? { /* compiled code */ }
There doesn't appear to be a definition in any of the knm files for udev_list_entry
(a C struct), however cnames.structs.udev_list_entry
does exist but its definition doesn't seem to appear in any of the knm files which is strange.napperley
08/26/2019, 2:54 AMudev_list_entry_foreach
which is used to access each entry in the list. Would manually iterating over the list (via udev_list_entry_get_next
) be the way to workaround the macro? I am using this C example as a reference: https://github.com/gavv/snippets/blob/master/udev/udev_monitor_usb.cnapperley
08/26/2019, 2:54 AMudev_list_entry_foreach
which is used to access each entry in the list. Would manually iterating over the list (via udev_list_entry_get_next
) be the way to workaround the macro? I am using this C example as a reference: https://github.com/gavv/snippets/blob/master/udev/udev_monitor_usb.c> Task :runSerial_reading_demoReleaseExecutableLinux
Starting USB monitor example...
Device Path: /sys/devices/pci0000:00/0000:00:14.0/usb1/1-0:1.0
* Device: Action - exists, Vendor - 0000, Product - 0000
Device Path: /sys/devices/pci0000:00/0000:00:14.0/usb1/1-0:1.0
* Device: Action - exists, Vendor - 0000, Product - 0000
lsusb
command:
Bus 002 Device 002: ID 0bda:0316 Realtek Semiconductor Corp.
Bus 002 Device 008: ID 2109:0813 VIA Labs, Inc.
Bus 002 Device 007: ID 2109:0813 VIA Labs, Inc.
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 004: ID 04f2:b604 Chicony Electronics Co., Ltd
Bus 001 Device 013: ID 10c4:ea60 Cygnal Integrated Products, Inc. CP210x UART Bridge / myAVR mySmartUSB light
Bus 001 Device 012: ID 2109:2813 VIA Labs, Inc.
Bus 001 Device 011: ID 2109:2813 VIA Labs, Inc.
Bus 001 Device 002: ID 046d:c52f Logitech, Inc. Unifying Receiver
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
msink
08/26/2019, 6:02 AMstruct udev_list_entry {
struct udev_list *list;
char *name;
char *value;
LIST_FIELDS(struct udev_list_entry, entries);
};
napperley
08/26/2019, 6:44 AMudev_enumerate_get_list_entry
to a property 🤦♂️. Iterating through the registered devices now looks like this:
val devices = udev_enumerate_get_list_entry(enumerate)
val usbDevices = mutableListOf<UsbDevice>()
if (devices != null) {
val tmp = processListEntry(udev, devices)
if (tmp.vendor.isNotEmpty()) usbDevices += tmp
}
var entry = udev_list_entry_get_next(devices)
while (entry != null) {
val tmp = processListEntry(udev, entry)
if (tmp.vendor.isNotEmpty()) usbDevices += tmp
entry = udev_list_entry_get_next(entry)
}
usbDevices.forEach { println("* $it") }
println("Total USB Devices: ${usbDevices.size}")
Dominaezzz
08/26/2019, 10:43 AMgenerateSequence
, you might find it useful here.