I created a Kotlin Multiplatform project based on the example for iOS and Android (https://kotlinlang.org/docs/tutorials/native/mpp-ios-android.html). Within my iOS target, I am using cinterop to link in a 3rd party Objective-C framework. This is working fine. I am able to reference the framework classes in my Kotlin code within the 'iosMain' source set. However, one of the method calls requires an NSError** parameter. I am attempting to use the following to create this variable in my Kotlin code:
kotlinx.cinterop.NativePlacement.allocPointerTo<kotlinx.cinterop.ObjCObjectVar<platform.Foundation.NSError?>()
I have not been able to find away around the following errors:
> Task :sharedLib:linkMainDebugFrameworkIOS FAILED
src/iosMain/kotlin/Platform.kt:9:50: error: unresolved reference: allocPointerTo
val error = kotlinx.cinterop.NativePlacement.allocPointerTo<kotlinx.cinterop.ObjCObjectVar<platform.Foundation.NSError?>()
^
src/iosMain/kotlin/Platform.kt:9:126: error: no value passed for parameter 'rawPtr'
val error = kotlinx.cinterop.NativePlacement.allocPointerTo<kotlinx.cinterop.ObjCObjectVar<platform.Foundation.NSError?>()
My understanding is that this package is part of stdlib, which should be added as a dependency automatically. Am I missing a piece of the equation somewhere?
UPDATE
The following is an example of passing an NSError* reference from Kotlin:
memScoped {
val errorRef = alloc<ObjCObjectVar<NSError?>>()
someObjCObject.method(errorRef.ptr)
}
kotlinx.cinterop.NativePlacement
is an interface name, not a class name. You need an instance of the NativePlacement
interface to work. For example memscoped{..}
block will work, e.g.
import kotlinx.cinterop.*
import platform.Foundation.*
val p = memScoped {
allocPointerTo<ObjCObjectVar<NSError?>>()
}
The memscoped{..}
accepts a lambda, inside the lambda the receiver implements the NativePlacement
type, so there is no need for a qualifier to call a function on it
https://kotlinlang.org/docs/reference/lambdas.html#function-literals-with-receiver