Implement scope-local C pointer. (#1471)
This commit is contained in:
+16
@@ -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`.
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user