【问题标题】:How to cast Kotlin interface to a class which implements it in kotlin-native dynamic library?如何将 Kotlin 接口转换为在 kotlin-native 动态库中实现它的类?
【发布时间】:2022-11-04 09:56:21
【问题描述】:

我正在尝试实现 kotlin-native 动态库并在 c++ 代码中使用它。 例如,我有以下代码,创建一个实例的函数响应Impl并返回接口回复

interface Response
    
class ResponseImpl(val text: String) : Response
    
fun getResponse(): Response = ResponseImpl(text = "This is the ResponseImpl instance")    

任务./gradlew :shared:linkReleaseSharedMacosX64在头文件中为我生成以下行:

  struct {
    struct {
      struct {
        struct {
          struct {
            libNativeTest_kref_com_test_nativesample_Response (*getResponse)();
            struct {
              libNativeTest_KType* (*_type)(void);
            } Response;
            struct {
              libNativeTest_KType* (*_type)(void);
              libNativeTest_kref_com_test_nativesample_ResponseImpl (*ResponseImpl)(const char* text);
              const char* (*get_text)(libNativeTest_kref_com_test_nativesample_ResponseImpl thiz);
            } ResponseImpl;
          } nativesample;
        } test;
      } com;
    } root;
  } kotlin;
} libNativeTest_ExportedSymbols;

在我调用的 C++ 代码中获取响应()功能并尝试访问文本财产。是实例总是正确的,但文本属性始终为空。

#include <iostream>
#include "libNativeTest_api.h"

int main() {
    auto lib = libNativeTest_symbols();
    auto packet = lib->kotlin.root.com.test.nativesample;

    auto response = packet.getResponse();

    bool isInstance = lib->IsInstance(response.pinned, packet.ResponseImpl._type());

    if (isInstance) {
        auto casted_response = (libNativeTest_kref_com_test_nativesample_ResponseImpl *) response.pinned;
        auto text = packet.ResponseImpl.get_text(*casted_response);
        if (text == nullptr) {
            std::cout << "TEXT IS NULL" << std::endl;
        } else {
            std::cout << text << std::endl;
        }
    }
    return 0;
}

将 Kotlin 接口转换为其实现类以访问详细信息的正确方法是什么?

【问题讨论】:

    标签: kotlin kotlin-multiplatform kotlin-native


    【解决方案1】:
    // Response.kt
    // just onto root package
    interface Response
    
    class ResponseImpl(val text: String) : Response
    
    fun getResponse(): Response = ResponseImpl(text = "This is the ResponseImpl instance")
    

    无需使用pinned,其中pinned 不能转换为 (libNativeTest_kref_com_test_nativesample_ResponseImpl *)

    // main.c
    #include <stdio.h>
    #include "libnative_api.h"
    
    int main(int argc, char **argv) {
        libnative_ExportedSymbols *symbols = libnative_symbols();
        libnative_kref_Response response = symbols->kotlin.root.getResponse();
        libnative_kref_ResponseImpl *responseImpl = (libnative_kref_ResponseImpl*)&response;
        printf("Response: %s
    ", symbols->kotlin.root.ResponseImpl.get_text(*responseImpl));
        return 0;
    }
    
    //output
    Response: This is the ResponseImpl instance
    

    【讨论】:

      猜你喜欢
      • 2017-03-02
      • 1970-01-01
      • 1970-01-01
      • 2018-09-03
      • 2020-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-08
      相关资源
      最近更新 更多