思念是回忆的愁 發表於 2022-4-1 18:46:00

【Flutter】Flutter C/C++ 插件的开发 (支持 windows、macos、ios、android )

<p>一个各平台调用 C/C++ 源码的例子,如何共享代码,配置相关的编译</p>
<p>官方的例子:https://docs.flutter.dev/development/platform-integration/c-interop</p>
<p>源码地址:https://github.com/gaoshang212/flutter_native_demo</p>
<h3 id="创建一个插件">创建一个插件</h3>
<p>可以执行下面的命令来创建一个插件</p>
<pre><code class="language-bash">flutter create --template=plugin --platforms=windows,macos,ios,android,linux flutter_native_demo
</code></pre>
<p>--platforms 可以指定支持哪些平台,如 windows,macos,ios,android,linux</p>
<p>如果没有创建相应平台目录,可以使用下面的命令开启相应的平台</p>
<pre><code class="language-bash">flutter config --enable-linux-desktop# 开启linux 桌面
flutter config --enable-macos-desktop# 开启macos 桌面
flutter config --enable-ios # 开启ios

# 更多的命令可以通过help查看
flutter config --help
</code></pre>
<p>如果有字符串操作或转换,可以添加 ffi 的包:</p>
<pre><code class="language-bash">flutter pub add ffi
</code></pre>
<p>项目结构</p>
<p><img src="https://img2022.cnblogs.com/blog/486019/202204/486019-20220401183828520-1559973853.png"></p>
<h3 id="添加-cc-源码文件">添加 C/C++ 源码文件</h3>
<p>很多时候我们各平台是会共用一套C/C++ 源码的,我们先创建一个源码,就按官网的来,但我们创建在一个公共目录(官网创建在IOS/Classes下面)</p>
<p><em>libs/native_add/native_add.cpp</em></p>
<pre><code class="language-cpp">#include &lt;stdint.h&gt;

#ifdef WIN32
#define DART_API extern "C" __declspec(dllexport)
#else
#define DART_API extern "C" __attribute__((visibility("default"))) __attribute__((used))
#endif

DART_API int32_t native_add(int32_t x, int32_t y) {
    return x + y;
}
</code></pre>
<h3 id="dart">Dart</h3>
<p>在 <em>lib/flutter_native_demo.dart</em> 中添加动态库的调用代码</p>
<pre><code class="language-dart">final DynamicLibrary nativeAddLib = Platform.isMacOS || Platform.isIOS
    ? DynamicLibrary.process()
    : DynamicLibrary.open('libNativeAdd.${Platform.isWindows ? 'dll' : 'so'}');

final int Function(int x, int y) nativeAdd = nativeAddLib
    .lookup&lt;NativeFunction&lt;Int32 Function(Int32, Int32)&gt;&gt;('native_add')
    .asFunction();
</code></pre>
<p>我们改一下 <em>example/lib/main.dart</em> 的代码</p>
<pre><code class="language-dart">// 修改一下 platformVersion 的赋值
platformVersion = nativeAdd(1, 2).toString();
</code></pre>
<h3 id="windows-配置">Windows 配置</h3>
<p>在 <em>libs/native_add</em> 目录中添加一个 CMakeLists.txt ,用来编译 动态库。</p>
<pre><code class="language-makefile">cmake_minimum_required(VERSION 3.10)

# 项目名称
set(PROJECT_NAME "libNativeAdd")
project(${PROJECT_NAME} LANGUAGES CXX)

# 源文件
add_library(${PROJECT_NAME} SHARED
    "./native_add.cpp"
)

# 动态库的输出目录
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/$&lt;$&lt;CONFIG:DEBUG&gt;:Debug&gt;$&lt;$&lt;CONFIG:RELEASE&gt;:Release&gt;")
# 安装动态库的目标目录
set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}")
# 安装动态库,到执行目录
install(FILES "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${PROJECT_NAME}.dll" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime)
</code></pre>
<p>在 <em>windows</em> 目录下面的<em>CMakeLists.txt</em> 中添加相应的子目录</p>
<pre><code class="language-makefile">add_subdirectory("../libs/native_add" native_add)
</code></pre>
<p>在 <em>example</em> 目录下面执行下面的命令,来运行程序.</p>
<pre><code class="language-powershell">cd example
flutter run -d windows -v
</code></pre>
<h3 id="android-配置">Android 配置</h3>
<p>安卓的动态库,会自动添加lib头,我们改造一下 <em>libs/native_add/CMakeLists.txt</em> 让他兼容windows和 android</p>
<pre><code class="language-makefile">cmake_minimum_required(VERSION 3.4)

# 项目名称
if (CMAKE_SYSTEM_NAME MATCHES "Windows")
    set(PROJECT_NAME "libNativeAdd")
else()
    set(PROJECT_NAME "NativeAdd")
endif()

project(${PROJECT_NAME} LANGUAGES CXX)

# 源文件
add_library(${PROJECT_NAME} SHARED
    "./native_add.cpp"
)

# Windows 需要把dll拷贝到bin目录
IF (WIN32)
    # 动态库的输出目录
    set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/$&lt;$&lt;CONFIG:DEBUG&gt;:Debug&gt;$&lt;$&lt;CONFIG:RELEASE&gt;:Release&gt;")
    # 安装动态库的目标目录
    set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}")
    # 安装动态库,到执行目录
    install(FILES "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${PROJECT_NAME}.dll" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime)
ENDIF()
</code></pre>
<p>在 android/build.gradle 文件中添加 CMakeList.txt 路径</p>
<pre><code>android {
        externalNativeBuild {
      // Encapsulates your CMake build configurations.
      cmake {
                        // 指定一个CMake 编译脚本的相对目录。
            path "../libs/native_add/CMakeLists.txt"
      }
   }
}
</code></pre>
<p>在 <em>example</em> 目录下面执行下面的命令,来运行程序</p>
<pre><code class="language-powershell">cd example
flutter run -d &lt;android&gt; -v
</code></pre>
<p>说明:可以用 <em>flutter devices</em> 查看支持设备,来替换 <em></android></em>。</p>
<h3 id="macos-配置">macOS 配置</h3>
<p>在 <em>macos/Classes</em> 目录中执行下面的命令,给macOS <em>link</em> 相关的代码</p>
<pre><code class="language-bash">ln -s ../../libs/native_add/native_add.cpp ./
</code></pre>
<p>然后回到 <em>example</em> 目录中执行</p>
<pre><code class="language-bash">flutter run -d macos -v
</code></pre>
<p>说明:国内使用时会,通过 <strong><strong>CocoaPods</strong></strong> 安装包会很慢,可以切换到 清华的镜像。设置 <em>example 目录下macos 的 Podfile。</em></p>
<h3 id="ios-配置">IOS 配置</h3>
<p>IOS 和 macOS 的配置基本是一样的,注意一下目录就好了。</p>
<h3 id="执行效果">执行效果</h3>
<p><img src="https://img2022.cnblogs.com/blog/486019/202204/486019-20220401184518197-1027959682.png"></p>
<p><img src="https://img2022.cnblogs.com/blog/486019/202204/486019-20220401184522391-1310919260.png"></p>


</div>
<div id="MySignature" role="contentinfo">
    本文原创手打,转载请注明出处。 Electron 交流 QQ:160162552<br><br>
来源:https://www.cnblogs.com/gaoshang212/p/16088491.html
頁: [1]
查看完整版本: 【Flutter】Flutter C/C++ 插件的开发 (支持 windows、macos、ios、android )