一個各平臺調用 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.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}/$<$<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 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}/$<$<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 的配置基本是一樣的,注意一下目錄就好了。