Skip to content

Commit

Permalink
Implement scope-local C pointer. (JetBrains#1471)
Browse files Browse the repository at this point in the history
  • Loading branch information
olonho authored Apr 5, 2018
1 parent 98a48be commit ddcbe68
Show file tree
Hide file tree
Showing 7 changed files with 29 additions and 9 deletions.
16 changes: 16 additions & 0 deletions INTEROP.md
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,22 @@ manually:
In all cases the C string is supposed to be encoded as UTF-8.
### Scope-local pointers ###
It is possible to create scope-stable pointer of C representation of `CValues<T>`
instance using `CValues<T>.ptr` extension property available under memScoped { ... }.
It allows to use APIs which requires C pointers with lifetime bound to certain `MemScope`. For example:
```
memScoped {
items = arrayOfNulls<CPointer<ITEM>?>(6)
arrayOf("one", "two").forEachIndexed { index, value -> items[index] = value.cstr.ptr }
menu = new_menu("Menu".cstr.ptr, items.toCValues().ptr)
...
}
```
In this example all values passed to the C API `new_menu()` have lifetime of innermost `memScope`
it belongs to. Once control flow will leave `memScoped` scope C pointers become invalid.
### Passing and receiving structs by value ###
When C function takes or returns a struct `T` by value, the corresponding
Expand Down
3 changes: 3 additions & 0 deletions Interop/Runtime/src/main/kotlin/kotlinx/cinterop/Utils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,9 @@ class MemScope : ArenaBase() {

val memScope: MemScope
get() = this

val <T: CVariable> CValues<T>.ptr: CPointer<T>
get() = this@ptr.getPointer(this@MemScope)
}

// TODO: consider renaming `memScoped` because it now supports `defer`.
Expand Down
3 changes: 2 additions & 1 deletion samples/androidNativeActivity/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ buildscript {

repositories {
jcenter()
google()
}

apply plugin: 'konan'
Expand Down Expand Up @@ -81,4 +82,4 @@ task buildApk(type: Copy) {
dependsOn "assembleDebug"
destinationDir outDir
from 'build/outputs/apk'
}
}
8 changes: 4 additions & 4 deletions samples/androidNativeActivity/src/main/kotlin/renderer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -306,10 +306,10 @@ class Renderer(val parentArena: NativePlacement, val nativeActivity: ANativeActi
}

glFrontFace(GL_CW)
glVertexPointer(4, GL_FLOAT, 0, vertices.toFloatArray().toCValues().getPointer(this))
glTexCoordPointer(2, GL_FLOAT, 0, texCoords.toFloatArray().toCValues().getPointer(this))
glNormalPointer(GL_FLOAT, 0, normals.toFloatArray().toCValues().getPointer(this))
glDrawElements(GL_TRIANGLES, triangles.size, GL_UNSIGNED_BYTE, triangles.toByteArray().toCValues().getPointer(this))
glVertexPointer(4, GL_FLOAT, 0, vertices.toFloatArray().toCValues().ptr)
glTexCoordPointer(2, GL_FLOAT, 0, texCoords.toFloatArray().toCValues().ptr)
glNormalPointer(GL_FLOAT, 0, normals.toFloatArray().toCValues().ptr)
glDrawElements(GL_TRIANGLES, triangles.size, GL_UNSIGNED_BYTE, triangles.toByteArray().toCValues().ptr)

glPopMatrix()

Expand Down
2 changes: 1 addition & 1 deletion samples/gtk/src/main/kotlin/Main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ fun gtkMain(args: Array<String>): Int {
g_signal_connect(app, "activate", staticCFunction(::activate))
val status = memScoped {
g_application_run(app.reinterpret(),
args.size, args.map { it.cstr.getPointer(memScope) }.toCValues())
args.size, args.map { it.cstr.ptr }.toCValues())
}
g_object_unref(app)
return status
Expand Down
4 changes: 2 additions & 2 deletions samples/nonBlockingEchoServer/src/main/kotlin/EchoServer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ fun main(args: Array<String>) {
val bufferLength = 100L
val buffer = allocArray<ByteVar>(bufferLength)
val connectionIdString = "#${++connectionId}: ".cstr
val connectionIdBytes = connectionIdString.getPointer(this)
val connectionIdBytes = connectionIdString.ptr

try {
while (true) {
Expand Down Expand Up @@ -212,4 +212,4 @@ inline fun Long.ensureUnixCallResult(predicate: (Long) -> Boolean): Long {
throw Error(getUnixError())
}
return this
}
}
2 changes: 1 addition & 1 deletion samples/uikit/src/main/kotlin/main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import platform.UIKit.*
fun main(args: Array<String>) {
memScoped {
val argc = args.size + 1
val argv = (arrayOf("konan") + args).map { it.cstr.getPointer(memScope) }.toCValues()
val argv = (arrayOf("konan") + args).map { it.cstr.ptr }.toCValues()

autoreleasepool {
UIApplicationMain(argc, argv, null, NSStringFromClass(AppDelegate))
Expand Down

0 comments on commit ddcbe68

Please sign in to comment.