Как создать void * указатель на kotlin native - PullRequest
0 голосов
/ 05 апреля 2020

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

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

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

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

приводит к

Native interop types constructors must not be called directly

ive read: kotlin inerop

Любая подсказка приветствуется.

Ответы [ 2 ]

1 голос
/ 06 апреля 2020

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

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.

0 голосов
/ 06 апреля 2020

@ Basur! Нельзя использовать Directpy для создания экземпляров типов указателей. Попробуйте разместить их в куче или внутри блока 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)
...