Improve Windows interop (#2022)
This commit is contained in:
@@ -375,16 +375,16 @@ fun List<String>.toCStringArray(autofreeScope: AutofreeScope): CPointer<CPointer
|
||||
fun Array<String>.toCStringArray(autofreeScope: AutofreeScope): CPointer<CPointerVar<ByteVar>> =
|
||||
autofreeScope.allocArrayOf(this.map { it.cstr.getPointer(autofreeScope) })
|
||||
|
||||
val String.wcstr: CValues<ShortVar>
|
||||
val String.wcstr: CValues<UShortVar>
|
||||
get() {
|
||||
val chars = CharArray(this.length, { i -> this.get(i)})
|
||||
return object : CValues<ShortVar>() {
|
||||
return object : CValues<UShortVar>() {
|
||||
override val size get() = 2 * (chars.size + 1)
|
||||
|
||||
override fun getPointer(scope: AutofreeScope): CPointer<ShortVar> {
|
||||
val result = scope.allocArray<ShortVar>(chars.size + 1)
|
||||
override fun getPointer(scope: AutofreeScope): CPointer<UShortVar> {
|
||||
val result = scope.allocArray<UShortVar>(chars.size + 1)
|
||||
nativeMemUtils.putCharArray(chars, result.pointed, chars.size)
|
||||
result[chars.size] = 0.toShort()
|
||||
result[chars.size] = 0u
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,6 +129,21 @@ fun CPointer<ShortVar>.toKString(): String {
|
||||
return String(bytes)
|
||||
}
|
||||
|
||||
fun CPointer<UShortVar>.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
|
||||
|
||||
+3
-2
@@ -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)"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -2,6 +2,13 @@ import kotlinx.cinterop.*
|
||||
import platform.windows.*
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
MessageBoxW(null, "Konan говорит:\nЗДРАВСТВУЙ МИР!\n",
|
||||
val message = StringBuilder()
|
||||
memScoped {
|
||||
val buffer = allocArray<UShortVar>(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())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user