1. 程式人生 > 其它 >【Flutter】Flutter C/C++ 外掛的開發 (支援 windows、macos、ios、android )

【Flutter】Flutter C/C++ 外掛的開發 (支援 windows、macos、ios、android )

一個各平臺呼叫 C/C++ 原始碼的例子,如何共享程式碼,配置相關的編譯

官方的例子:https://docs.flutter.dev/development/platform-integration/c-interop

原始碼地址:https://github.com/gaoshang212/flutter_native_demo

建立一個外掛

可以執行下面的命令來建立一個外掛

flutter create --template=plugin --platforms=windows,macos,ios,android,linux flutter_native_demo

--platforms 可以指定支援哪些平臺,如 windows,macos,ios,android,linux

如果沒有建立相應平臺目錄,可以使用下面的命令開啟相應的平臺

flutter config --enable-linux-desktop  # 開啟linux 桌面
flutter config --enable-macos-desktop  # 開啟macos 桌面
flutter config --enable-ios # 開啟ios

# 更多的命令可以通過help檢視
flutter config --help

如果有字串操作或轉換,可以新增 ffi 的包:

flutter pub add ffi

專案結構

新增 C/C++ 原始碼檔案

很多時候我們各平臺是會共用一套C/C++ 原始碼的,我們先建立一個原始碼,就按官網的來,但我們建立在一個公共目錄(官網建立在IOS/Classes下面)

libs/native_add/native_add.cpp

#include <stdint.h>

#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;
}

Dart

lib/flutter_native_demo.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<NativeFunction<Int32 Function(Int32, Int32)>>('native_add')
    .asFunction();

我們改一下 example/lib/main.dart 的程式碼

// 修改一下 platformVersion 的賦值
platformVersion = nativeAdd(1, 2).toString();

Windows 配置

libs/native_add 目錄中新增一個 CMakeLists.txt ,用來編譯 動態庫。

cmake_minimum_required(VERSION 3.4)

# 專案名稱
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}/$<$<CONFIG:DEBUG>:Debug>$<$<CONFIG:RELEASE>:Release>")
# 安裝動態庫的目標目錄
set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}")
# 安裝動態庫,到執行目錄
install(FILES "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${PROJECT_NAME}.dll" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime)

windows 目錄下面的 CMakeLists.txt 中新增相應的子目錄

add_subdirectory("../libs/native_add" native_add)

example 目錄下面執行下面的命令,來執行程式.

cd example
flutter run -d windows -v

Android 配置

安卓的動態庫,會自動新增lib頭,我們改造一下 libs/native_add/CMakeLists.txt 讓他相容windows和 android

cmake_minimum_required(VERSION 3.4)

# 專案名稱
if (${CMAKE_SYSTEM_NAME} EQUAL "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}/$<$<CONFIG:DEBUG>:Debug>$<$<CONFIG:RELEASE>:Release>")
    # 安裝動態庫的目標目錄
    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()

在 android/build.gradle 檔案中新增 CMakeList.txt 路徑

android {
	externalNativeBuild {
        // Encapsulates your CMake build configurations.
        cmake {
		        // 指定一個CMake 編譯指令碼的相對目錄。
            path "../libs/native_add/CMakeLists.txt"
        }
   }
}

example 目錄下面執行下面的命令,來執行程式

cd example
flutter run -d <android> -v

說明:可以用 flutter devices 檢視支援裝置,來替換

macOS 配置

macos/Classes 目錄中執行下面的命令,給macOS link 相關的程式碼

ln -s ../../libs/native_add/native_add.cpp ./

然後回到 example 目錄中執行

flutter run -d macos -v

說明:國內使用時會,通過 CocoaPods 安裝包會很慢,可以切換到 清華的映象。設定 example 目錄下macos 的 Podfile。

IOS 配置

IOS 和 macOS 的配置基本是一樣的,注意一下目錄就好了。

執行效果