Skip to content

Commit

Permalink
Fix problem with conversion of Kotlin String to C char * (#827)
Browse files Browse the repository at this point in the history
(cherry picked from commit ec84059)
  • Loading branch information
dima-avdeev-jb committed Nov 15, 2023
1 parent 1cbde7b commit 1601e9f
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 5 deletions.
1 change: 1 addition & 0 deletions skiko/RELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ build configuration.
```bash
./gradlew publishToMavenLocal -Pskiko.native.enabled=true -Pskiko.wasm.enabled=true -Pskiko.android.enabled=true
```
Use flag `-Pskiko.debug=true` to build with debug build type.

##### Publish to `build/repo` directory
```bash
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,7 @@ internal actual inline fun <T> interopScope(block: InteropScope.() -> T): T {
internal actual class InteropScope actual constructor() {
actual fun toInterop(string: String?): InteropPointer {
return if (string != null) {
// encodeToByteArray encodes to utf8
val utf8 = string.encodeToByteArray()
// TODO Remove array copy, use `skString(data, length)` instead of `skString(data)`
val pinned = utf8.copyOf(utf8.size + 1).pin()
val pinned = convertToZeroTerminatedString(string).pin()
elements.add(pinned)
val result = pinned.addressOf(0).rawValue
result
Expand Down Expand Up @@ -186,7 +183,7 @@ internal actual class InteropScope actual constructor() {
if (stringArray == null || stringArray.isEmpty()) return NativePtr.NULL

val pins = stringArray.toList()
.map { it.encodeToByteArray().pin() }
.map { convertToZeroTerminatedString(it).pin() }

val nativePointerArray = NativePointerArray(stringArray.size)
pins.forEachIndexed { index, pin ->
Expand Down Expand Up @@ -284,3 +281,14 @@ private external fun initCallbacks(
callVoid: COpaquePointer,
dispose: COpaquePointer
)

/**
* Converts String to zero-terminated utf-8 byte array.
*/
private fun convertToZeroTerminatedString(string: String): ByteArray {
// C++ needs char* with zero byte at the end. So we need to copy array with an extra zero byte.

val utf8 = string.encodeToByteArray() // encodeToByteArray encodes to utf8
// TODO Remove array copy, use `skString(data, length)` instead of `skString(data)`
return utf8.copyOf(utf8.size + 1)
}

0 comments on commit 1601e9f

Please sign in to comment.