3

我正在尝试使用本机库将现有的 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

我读过: kotlin inerop

任何提示表示赞赏。

4

2 回答 2

4

我找到了一个可行的解决方案。我犯了一个错误,并认为我的指针分配是错误的,所以我复制了 ide 认为正确的内容。导致分配如下:

var avar:COpaquePointerVar = alloc()

现在 Kotlin 本机可以正确分配所有内容。但是纯分配很少能解决问题,所以这里是代码:

/* 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 的人。

于 2020-04-06T14:02:59.617 回答
1

@巴苏尔!不能直接实例化指针类型。尝试将它们分配在堆上或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)
于 2020-04-06T13:43:11.517 回答