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>> =
|
fun Array<String>.toCStringArray(autofreeScope: AutofreeScope): CPointer<CPointerVar<ByteVar>> =
|
||||||
autofreeScope.allocArrayOf(this.map { it.cstr.getPointer(autofreeScope) })
|
autofreeScope.allocArrayOf(this.map { it.cstr.getPointer(autofreeScope) })
|
||||||
|
|
||||||
val String.wcstr: CValues<ShortVar>
|
val String.wcstr: CValues<UShortVar>
|
||||||
get() {
|
get() {
|
||||||
val chars = CharArray(this.length, { i -> this.get(i)})
|
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 val size get() = 2 * (chars.size + 1)
|
||||||
|
|
||||||
override fun getPointer(scope: AutofreeScope): CPointer<ShortVar> {
|
override fun getPointer(scope: AutofreeScope): CPointer<UShortVar> {
|
||||||
val result = scope.allocArray<ShortVar>(chars.size + 1)
|
val result = scope.allocArray<UShortVar>(chars.size + 1)
|
||||||
nativeMemUtils.putCharArray(chars, result.pointed, chars.size)
|
nativeMemUtils.putCharArray(chars, result.pointed, chars.size)
|
||||||
result[chars.size] = 0.toShort()
|
result[chars.size] = 0u
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -129,6 +129,21 @@ fun CPointer<ShortVar>.toKString(): String {
|
|||||||
return String(bytes)
|
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")
|
@SymbolName("Kotlin_interop_malloc")
|
||||||
private external fun malloc(size: Long, align: Int): NativePtr
|
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.
|
// 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 {
|
private fun getArrayLength(type: ArrayType): Long {
|
||||||
val unwrappedElementType = type.elemType.unwrapTypedefs()
|
val unwrappedElementType = type.elemType.unwrapTypedefs()
|
||||||
@@ -629,7 +630,7 @@ class StubGenerator(
|
|||||||
kotlinParameters.add(parameterName to KotlinTypes.string.makeNullable())
|
kotlinParameters.add(parameterName to KotlinTypes.string.makeNullable())
|
||||||
bodyGenerator.pushMemScoped()
|
bodyGenerator.pushMemScoped()
|
||||||
"$parameterName?.cstr?.getPointer(memScope)"
|
"$parameterName?.cstr?.getPointer(memScope)"
|
||||||
} else if (representCFunctionParameterAsWString(parameter.type)) {
|
} else if (representCFunctionParameterAsWString(func, parameter.type)) {
|
||||||
kotlinParameters.add(parameterName to KotlinTypes.string.makeNullable())
|
kotlinParameters.add(parameterName to KotlinTypes.string.makeNullable())
|
||||||
bodyGenerator.pushMemScoped()
|
bodyGenerator.pushMemScoped()
|
||||||
"$parameterName?.wcstr?.getPointer(memScope)"
|
"$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 \
|
compilerOpts = -DUNICODE -DWINVER=0x0601 -D_WIN32_WINNT=0x0601 -DWINAPI_FAMILY=3 -DOEMRESOURCE \
|
||||||
-Wno-incompatible-pointer-types -Wno-deprecated-declarations
|
-Wno-incompatible-pointer-types -Wno-deprecated-declarations
|
||||||
linkerOpts = -lcomctl32 -lcrypt32 -lshlwapi -lshell32 -limm32 -lusp10 -lwininet -lgdi32 -luser32 -lkernel32
|
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
|
depends = posix
|
||||||
|
|||||||
@@ -2,6 +2,13 @@ import kotlinx.cinterop.*
|
|||||||
import platform.windows.*
|
import platform.windows.*
|
||||||
|
|
||||||
fun main(args: Array<String>) {
|
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())
|
"Заголовок окна", (MB_YESNOCANCEL or MB_ICONQUESTION).convert())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user