Implement scope-local C pointer. (#1471)

This commit is contained in:
Nikolay Igotti
2018-04-05 19:30:10 +03:00
committed by GitHub
parent 98a48be0e5
commit ddcbe68a5b
7 changed files with 29 additions and 9 deletions
+16
View File
@@ -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
@@ -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`.
+2 -1
View File
@@ -15,6 +15,7 @@ buildscript {
repositories {
jcenter()
google()
}
apply plugin: 'konan'
@@ -81,4 +82,4 @@ task buildApk(type: Copy) {
dependsOn "assembleDebug"
destinationDir outDir
from 'build/outputs/apk'
}
}
@@ -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()
+1 -1
View File
@@ -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
@@ -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) {
@@ -212,4 +212,4 @@ inline fun Long.ensureUnixCallResult(predicate: (Long) -> Boolean): Long {
throw Error(getUnixError())
}
return this
}
}
+1 -1
View File
@@ -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))