Как создать указатель void * для kotlin native

Я пытаюсь преобразовать существующий код c в kotlin с помощью собственной библиотеки. до сих пор ive успешно запустился, но испытывает трудности с указателями, которые используются для доступа к структурам или объектам. как это в c:

void *ptr;
foo(&ptr); //init is done inside
bar(&ptr); //ptr is reused

но как сохранить эти указатели в котлине? такие попытки:

var avar = CPointerVarOf<COpaquePointer>(NativePtr.NULL)
var bvar: CPointerVarOf<CPointer<*>> = null

приводит к

Native interop types constructors must not be called directly

Я прочел: kotlin inerop

Любой намек приветствуется.


person Basur    schedule 05.04.2020    source источник


Ответы (2)


Нашел рабочее решение. Я сделал ошибку и подумал, что у меня неправильное выделение указателя, поэтому я скопировал то, что ide считал правильным. что привело к распределению вроде:

var avar:COpaquePointerVar = alloc()

теперь Kotlin native все размещает правильно. но чистое распределение редко решает проблему, поэтому вот код:

/* C Code */
void* adapter;
int ret;

ret = gattlib_adapter_open(NULL, &adapter);
if (ret) {
    fprintf(stderr, "ERROR: Failed to open adapter.\n");
    return 1;
}

ret = gattlib_adapter_scan_enable(adapter, ble_discovered_device, 5, NULL /* user_data */);
if (ret) {
    fprintf(stderr, "ERROR: Failed to scan.\n");
}

gattlib_adapter_scan_disable(adapter);

puts("Scan completed");

после того, как я заметил свою ошибку, я снова прочитал весь свой код и создал рабочий пример на c. Я переместил код по частям с c на kotlin native. так что версия kotlin прошла несколько этапов и закончилась:

/* Kotlin with native interop */
memScoped {
    var avar: COpaquePointerVar = alloc()
    var ret = gattlib_adapter_open(null, avar.ptr)
    print("Adapter opened\n")
    if (ret > 0) {
        print( "ERROR: Failed to open adapter.\n");
        return
    }

    print("start scan\n")
    gattlib_adapter_scan_enable(avar.value, staticCFunction { a, b, c, d ->
        kotlin.native.initRuntimeIfNeeded()
        print("found dev\n")
    }, 5, NULL /* user_data */);

    gattlib_adapter_scan_disable(avar.value)

    print("Scan completed\n");
}

Я студент, так что это может быть не лучшая практика, не стесняйтесь поправлять меня в любой момент. Я надеюсь, что этот фрагмент поможет всем, кто только начал работать с kotlin native.

person Basur    schedule 06.04.2020

@Basur! Нельзя напрямую создавать экземпляры указателей. Попробуйте разместить их в куче или внутри блока memScoped {...} следующим образом:

val voidy:COpaquePointerVar = nativeHeap.alloc()
fun a(ptr:CPointer<COpaquePointerVar>){
    println(ptr.pointed.value)
    ptr.pointed.value = NULL
}
fun b(ptr:CPointer<COpaquePointerVar>){
    println(ptr.pointed.value)
}
a(voidy.ptr)
b(voidy.ptr)
...
nativeHeap.free(voidy)
person Artyom Degtyarev    schedule 06.04.2020
comment
да, мне потребовалось около 16 часов, чтобы осознать это, и еще 3, чтобы найти свою ошибку в коде ... - person Basur; 06.04.2020
comment
Я написал ответ, пока вы это разместили, кажется немного глупым, если я сейчас увижу и понял, где была моя ошибка, я мог бы собрать коллекцию собственных примеров kotlin для начинающих, могу ли я использовать ваш код по ссылке или напрямую со ссылкой на ваш пост? - person Basur; 06.04.2020
comment
Хорошо, не стесняйтесь использовать его вообще без упоминаний, ваш IMHO???? даже лучше. Единственное, что я бы порекомендовал вам, - это немного обновить свой ответ: нет необходимости явно указывать тип, как вы, что-то вроде val avar:COpaquePointerVar = alloc() должно помочь. - person Artyom Degtyarev; 06.04.2020