diff --git a/Interop/Runtime/src/main/kotlin/kotlinx/cinterop/Utils.kt b/Interop/Runtime/src/main/kotlin/kotlinx/cinterop/Utils.kt index 2a9ff2b2b0d..02ae0e9db15 100644 --- a/Interop/Runtime/src/main/kotlin/kotlinx/cinterop/Utils.kt +++ b/Interop/Runtime/src/main/kotlin/kotlinx/cinterop/Utils.kt @@ -375,16 +375,16 @@ fun List.toCStringArray(autofreeScope: AutofreeScope): CPointer.toCStringArray(autofreeScope: AutofreeScope): CPointer> = autofreeScope.allocArrayOf(this.map { it.cstr.getPointer(autofreeScope) }) -val String.wcstr: CValues +val String.wcstr: CValues get() { val chars = CharArray(this.length, { i -> this.get(i)}) - return object : CValues() { + return object : CValues() { override val size get() = 2 * (chars.size + 1) - override fun getPointer(scope: AutofreeScope): CPointer { - val result = scope.allocArray(chars.size + 1) + override fun getPointer(scope: AutofreeScope): CPointer { + val result = scope.allocArray(chars.size + 1) nativeMemUtils.putCharArray(chars, result.pointed, chars.size) - result[chars.size] = 0.toShort() + result[chars.size] = 0u return result } } diff --git a/Interop/Runtime/src/native/kotlin/kotlinx/cinterop/NativeMem.kt b/Interop/Runtime/src/native/kotlin/kotlinx/cinterop/NativeMem.kt index cfc8f351ccd..5c2211239a1 100644 --- a/Interop/Runtime/src/native/kotlin/kotlinx/cinterop/NativeMem.kt +++ b/Interop/Runtime/src/native/kotlin/kotlinx/cinterop/NativeMem.kt @@ -129,6 +129,21 @@ fun CPointer.toKString(): String { return String(bytes) } +fun CPointer.toKString(): String { + val nativeBytes = this + + var length = 0 + while (nativeBytes[length] != 0.toUShort()) { + ++length + } + val bytes = CharArray(length) + var index = 0 + while (index < length) { + bytes[index] = nativeBytes[index].toShort().toChar() + ++index + } + return String(bytes) +} @SymbolName("Kotlin_interop_malloc") private external fun malloc(size: Long, align: Int): NativePtr diff --git a/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/StubGenerator.kt b/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/StubGenerator.kt index 00450b59981..d7f5e62440a 100644 --- a/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/StubGenerator.kt +++ b/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/StubGenerator.kt @@ -323,7 +323,8 @@ class StubGenerator( } // We take this approach as generic 'const short*' shall not be used as String. - fun representCFunctionParameterAsWString(type: Type)= type.isAliasOf(platformWStringTypes) + fun representCFunctionParameterAsWString(function: FunctionDecl, type: Type) = type.isAliasOf(platformWStringTypes) + && !noStringConversion.contains(function.name) private fun getArrayLength(type: ArrayType): Long { val unwrappedElementType = type.elemType.unwrapTypedefs() @@ -629,7 +630,7 @@ class StubGenerator( kotlinParameters.add(parameterName to KotlinTypes.string.makeNullable()) bodyGenerator.pushMemScoped() "$parameterName?.cstr?.getPointer(memScope)" - } else if (representCFunctionParameterAsWString(parameter.type)) { + } else if (representCFunctionParameterAsWString(func, parameter.type)) { kotlinParameters.add(parameterName to KotlinTypes.string.makeNullable()) bodyGenerator.pushMemScoped() "$parameterName?.wcstr?.getPointer(memScope)" diff --git a/platformLibs/src/platform/mingw/windows.def b/platformLibs/src/platform/mingw/windows.def index a7eddbc07f6..8724dc33a0c 100644 --- a/platformLibs/src/platform/mingw/windows.def +++ b/platformLibs/src/platform/mingw/windows.def @@ -4,5 +4,5 @@ headers = wtypes.h minwindef.h windows.h commctrl.h dwmapi.h shlobj.h shlwapi.h compilerOpts = -DUNICODE -DWINVER=0x0601 -D_WIN32_WINNT=0x0601 -DWINAPI_FAMILY=3 -DOEMRESOURCE \ -Wno-incompatible-pointer-types -Wno-deprecated-declarations linkerOpts = -lcomctl32 -lcrypt32 -lshlwapi -lshell32 -limm32 -lusp10 -lwininet -lgdi32 -luser32 -lkernel32 -noStringConversion = LoadCursorA LoadBitmapA +noStringConversion = LoadCursorA LoadBitmapA LoadIconA LoadImageA LoadCursorW LoadBitmapW LoadIconW LoadImageW depends = posix diff --git a/samples/win32/src/main/kotlin/MessageBox.kt b/samples/win32/src/main/kotlin/MessageBox.kt index 5403ad9a64e..a9aaa5048d6 100644 --- a/samples/win32/src/main/kotlin/MessageBox.kt +++ b/samples/win32/src/main/kotlin/MessageBox.kt @@ -2,6 +2,13 @@ import kotlinx.cinterop.* import platform.windows.* fun main(args: Array) { - MessageBoxW(null, "Konan говорит:\nЗДРАВСТВУЙ МИР!\n", + val message = StringBuilder() + memScoped { + val buffer = allocArray(MAX_PATH) + GetModuleFileNameW(null, buffer, MAX_PATH) + val path = buffer.toKString().split("\\").dropLast(1).joinToString("\\") + message.append("Я нахожусь в $path\n") + } + MessageBoxW(null, "Konan говорит:\nЗДРАВСТВУЙ МИР!\n$message", "Заголовок окна", (MB_YESNOCANCEL or MB_ICONQUESTION).convert()) }