【Flutter跨平台插件开发】如何实现kotlin跟C++的相互调用

这篇具有很好参考价值的文章主要介绍了【Flutter跨平台插件开发】如何实现kotlin跟C++的相互调用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【Flutter跨平台插件开发】如何实现kotlin跟C++的相互调用

kotlin 调 c++

在 Kotlin 中,可以使用 JNI (Java Native Interface) 来调用 C++ 代码

调用步骤:

  1. 创建 C++ 文件并实现函数。
// example.cpp
#include <jni.h>

extern "C" JNIEXPORT jstring JNICALL
Java_com_example_MyClass_myFunction(JNIEnv* env, jobject /* this */) {
    return env->NewStringUTF("Hello from C++");
}
  1. 在 Kotlin 中声明需要调用的 native 函数并加载 native 库。
class MyClass {
    external fun myFunction(): String

    companion object {
        init {
            System.loadLibrary("example") // example是库的名字
        }
    }
}
  1. 调用示例
val myClass = MyClass()
println(myClass.myFunction()) // 输出 "Hello from C++"

Flutter 插件项目的例子

在 Flutter 插件中引用已有的 C++ 源码需要以下步骤:

  1. 首先,在 Flutter 插件的 android 目录下创建一个 CMakeLists.txt 文件,这个文件会告诉 CMake 如何编译你的 C++ 代码。
cmake_minimum_required(VERSION 3.4.1)

add_library( # Specifies the name of the library.
             native-lib

             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
             src/main/cpp/native-lib.cpp )
  1. 然后,在插件的 build.gradle 文件中启用 CMake 并指定 CMakeLists.txt 文件的位置。
android {
    // ...

    defaultConfig {
        // ...

        externalNativeBuild {
            cmake {
                cppFlags ""
            }
        }
    }

    externalNativeBuild {
        cmake {
            path "CMakeLists.txt"
        }
    }
}
  1. 在 Kotlin 代码中,可以使用 System.loadLibrary 来加载库,并使用 external 关键字来声明 native 方法。
class MyPlugin: FlutterPlugin, MethodCallHandler {
    // ...

    external fun myNativeMethod(): String

    init {
        System.loadLibrary("native-lib")
    }

    // ...
}
  1. 最后,在 C++ 代码中实现函数。
#include <jni.h>

extern "C" JNIEXPORT jstring JNICALL
Java_com_example_MyPlugin_myNativeMethod(JNIEnv* env, jobject /* this */) {
    // 你的代码...
}
注意
  1. 需要使用 ndk-build 或者 CMake 来编译 C++ 代码,并将生成的库放到 Android 项目的 jniLibs 目录下。
  2. C++ 函数的名称必须遵循特定的格式:Java_包名_类名_方法名。在这个例子中,Java_com_example_MyClass_myFunction 对应于 com.example.MyClass 类的 myFunction 方法。

c++ 调 kotln

在 Kotlin 中,可以使用 JNI (Java Native Interface) 来设置回调到 C++ 代码。

同步调用(这个需要kotlin先调到cpp,cpp再调回来,都是同步操作)

  1. 在 Kotlin 中创建一个接口,该接口将被 C++ 代码调用。
interface Callback {
    fun onEvent(event: String)
}
  1. 创建一个 native 函数,kotlin 的回调函数将通过这个native函数,传给cpp
class MyClass {
    private var callback: Callback? = null

    fun setCallback(callback: Callback) {
        this.callback = callback
    }

    external fun triggerEvent()

    private fun onEvent(event: String) {
        callback?.onEvent(event)
    }

    companion object {
        init {
            System.loadLibrary("example")
        }
    }
}
  1. 在 C++ 代码中实现 triggerEvent 函数,从参数中获取 onEvent 方法并调用。
#include <jni.h>

extern "C" JNIEXPORT void JNICALL
Java_com_example_MyClass_triggerEvent(JNIEnv* env, jobject instance) {
    jclass cls = env->GetObjectClass(instance);
    jmethodID mid = env->GetMethodID(cls, "onEvent", "(Ljava/lang/String;)V");
    if (mid == nullptr) return; // method not found
    jstring message = env->NewStringUTF("Hello from C++");
    env->CallVoidMethod(instance, mid, message);
}

在这个例子中,triggerEvent 函数在 C++ 代码中被调用,然后它调用 Kotlin 中的 onEvent 方法,该方法然后调用 Callback 接口的 onEvent 方法。

方法签名

在 JNI (Java Native Interface) 中,“(Ljava/lang/String;)V” 是一个方法签名,用于描述方法的参数类型和返回值类型

这个签名可以被分解为以下部分:

  • 括号 “(” 和 “)”:括号内的内容描述了方法的参数类型。在这个例子中,“Ljava/lang/String;” 表示方法有一个参数,类型为 java.lang.String

  • “V”:这是方法的返回值类型。在 JNI 中,“V” 表示 void,也就是说这个方法没有返回值。

所以,“(Ljava/lang/String;)V” 这个签名表示的是一个接受一个 java.lang.String 参数并且没有返回值的方法。

其他一些常见的 JNI 类型签名包括:

  • “I”:表示 int
  • “J”:表示 long
  • “S”:表示 short
  • “B”:表示 byte
  • “C”:表示 char
  • “D”:表示 double
  • “F”:表示 float
  • “Z”:表示 boolean
  • “[I”:表示 int 数组
  • “Lfully/qualified/ClassName;”:表示 fully.qualified.ClassName 类型的对象

你可以在 JNI 文档中找到更多关于类型签名的信息。

异步回调

在 JNI 中,JNIEnv*jobject 通常不能直接保存起来用于异步回调。
这是因为:

  • JNIEnv* 是线程相关的,每个线程都有一个不同的 JNIEnv*。如果你在一个线程保存了 JNIEnv*,然后在另一个线程使用它,可能会导致问题。
  • 同样,jobject 是一个局部引用,它只在当前的 JNI 调用中有效,调用结束后就会被自动删除。

如果你需要在异步回调中使用这些对象,你需要做一些额外的步骤:

  1. 对于 JNIEnv*,你需要在回调的线程中通过 JavaVM* 获取一个新的 JNIEnv*。你可以在保存 JNIEnv* 的同时保存 JavaVM*,通过调用 JNIEnv->GetJavaVM(&jvm) 获取。

  2. 对于 jobject,你需要创建一个全局引用,这样它就可以跨越多个 JNI 调用。你可以通过调用 JNIEnv->NewGlobalRef(jobject) 来创建一个全局引用。记住在你不再需要这个全局引用时,需要调用 JNIEnv->DeleteGlobalRef(jobject) 来删除它,防止内存泄漏。

以下是一个简单的例子:

JavaVM* jvm;
jobject globalObj;

JNIEXPORT void JNICALL Java_MyClass_init(JNIEnv* env, jobject obj) {
    env->GetJavaVM(&jvm);
    globalObj = env->NewGlobalRef(obj);
}

void asyncCallback() {
    JNIEnv* env;
    jvm->AttachCurrentThread(&env, NULL);

    // 有了env跟obj后,这里参考上面同步调用的例子的实现

    jvm->DetachCurrentThread();
}

在这个例子中,Java_MyClass_init 是一个 JNI 方法,它保存了 JavaVM* 和一个全局引用。然后在 asyncCallback 中,我们获取了一个新的 JNIEnv*,并使用了全局引用。注意我们在回调结束时调用了 DetachCurrentThread,这是因为我们之前调用了 AttachCurrentThread。如果你在一个已经被附加到 JVM 的线程中调用回调,你不需要调用这两个方法。文章来源地址https://www.toymoban.com/news/detail-822279.html

到了这里,关于【Flutter跨平台插件开发】如何实现kotlin跟C++的相互调用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 我想开发一款跨平台桌面软件,请告诉我qt、electron、tauri、pyqt、flutter分别适合开发哪些跨平台桌面

    不同的跨平台桌面开发工具适用于不同的应用场景和开发者需求。以下是关于 Qt、Electron、Tauri、PyQt、Flutter 的简要说明,以帮助你更好地选择适合你项目的工具: Qt: 适用场景: Qt 是一个强大的 C++ 框架,适用于开发需要高性能和原生外观的桌面应用。它具有广泛的平台支持

    2024年02月22日
    浏览(79)
  • 从零基础到精通Flutter开发:一步步打造跨平台应用

    💂 个人网站:【工具大全】【游戏大全】【神级源码资源网】 🤟 前端学习课程:👉【28个案例趣学前端】【400个JS面试题】 💅 寻找学习交流、摸鱼划水的小伙伴,请点击【摸鱼学习交流群】 导言 Flutter是一种流行的开发框架,可以用来构建美观、高性能且跨平台的移动应

    2024年02月08日
    浏览(75)
  • Flutter实现Service + UI 全面跨平台

    作者:Karl_wei Flutter作为跨平台的UI框架,其可行性已经被市场所认可。UI跨端后,我们自然会希望一些运行在 终端的小服务也能跨端 ,特别是当这个小服务还涉及到一些 UI 的展示。 我们希望Flutter能承担这个角色,让其跨端能力更进一步。 我们希望在整机设备上,运行一个

    2024年02月12日
    浏览(50)
  • Flutter与Android开发:构建跨平台移动应用的新选择

    本文内容提纲如下: 介绍Flutter技术:Flutter是一种由Google推出的开源UI工具包,用于构建高性能、跨平台的移动应用。文章将介绍Flutter的基本概念、特点和优势,包括其快速的开发速度、一致的用户界面和丰富的UI组件库等。 Flutter与Android开发的对比:文章将对比Flutter与传统

    2023年04月21日
    浏览(186)
  • Android:手把手带你入门跨平台UI开发框架Flutter

    定义:一款Google出品开源的移动客户端UI开发框架(SDK) 作用:用一套代码同时在Android、iOS上快速构建高质量、高性能的原生用户界面 开发语言:Dart语言(高开发效率、高性能等) 2. 特点 Flutter的主要特点包括:使用自身的高性能渲染引擎进行渲染 Dart编程语言语言 具体介

    2024年04月13日
    浏览(68)
  • Flutter:引领移动开发新潮流,跨平台应用程序的终极解决方案

    Flutter是由Google开发的一款开源移动应用开发框架,它可以帮助开发者快速高效地构建跨平台的移动应用程序。Flutter基于Dart编程语言,具有简单易学、高效灵活的特点,并且可以与现有的Android和iOS应用进行集成。本文将介绍Flutter的基本概念、开发环境搭建、基础组件、生命

    2024年02月04日
    浏览(86)
  • 跨平台开发神器如何在Uniapp中使用WebView实现与Web页面的通讯!

    Uniapp 是一个跨平台的开发框架,可以同时开发出 iOS、Android、H5 等多个平台的应用。在开发过程中,我们可能需要与 Web 页面进行通讯,这时可以使用 WebView 组件来实现。 本教程将介绍如何在 uniapp 中使用 WebView 组件与 Web 页面进行通讯。 首先,我们需要创建一个 uniapp 项目。

    2024年02月09日
    浏览(61)
  • 【粉丝福利社】Flutter小白开发——跨平台客户端应用开发学习路线(文末送书-完结)

    🏆 作者简介,愚公搬代码 🏆《头衔》:华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主,腾讯云内容共创官,掘金优秀博主,51CTO博客专家等。 🏆《近期荣誉》:

    2024年01月16日
    浏览(79)
  • 【粉丝福利社】Flutter小白开发——跨平台客户端应用开发学习路线(文末送书-进行中)

    🏆 作者简介,愚公搬代码 🏆《头衔》:华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主,腾讯云内容共创官,掘金优秀博主,51CTO博客专家等。 🏆《近期荣誉》:

    2024年01月18日
    浏览(86)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包