您好,登錄后才能下訂單哦!
這篇文章主要介紹“如何使用C++實現Flutter Windows插件”,在日常操作中,相信很多人在如何使用C++實現Flutter Windows插件問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”如何使用C++實現Flutter Windows插件”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
上周實現的Flutter條形碼插件已經發布到https://pub.dev/packages/flutter_barcode_sdk,平臺相關部分只包含了Android的Java代碼。這周新增用于Windows的C++代碼。后續計劃還包含iOS和Web。
安裝包下載:https://www.dynamsoft.com/barcode-reader/downloads
30天試用序列號:https://www.dynamsoft.com/customer/license/trialLicense/?product=dbr
Flutter桌面插件開發的資源比較少。可以從以下三個入手:
https://flutter.dev/desktop
https://github.com/google/flutter-desktop-embedding
https://github.com/flutter/samples/tree/master/experimental/desktop_photo_search
Flutter創建的Windows插件工程目錄結構如下:
bin /DynamsoftBarcodeReaderx64.dll include /flutter_barcode_sdk /flutter_barcode_sdk_plugin.h /barcode_manager.h /DynamsoftBarcodeReader.h /DynamsoftCommon.h lib /DBRx64.lib CMakeLists.txt flutter_barcode_sdk_plugin.cpp
CMakeLists.txt
是CMake的配置文件。
flutter_barcode_sdk_plugin.cpp
用于實現插件的C++代碼邏輯。
DynamsoftBarcodeReaderx64.dll
,DBRx64.lib
,DynamsoftBarcodeReader.h
,以及DynamsoftCommon.h
可以從C++ SDK中獲取。
為了方便,條形碼接口調用的實現都放在barcode_manager.h
中。
從Dart傳到C++的接口和參數,會在HandleMethodCall()
中解析:
void FlutterBarcodeSdkPlugin::HandleMethodCall( const flutter::MethodCall<flutter::EncodableValue> &method_call, std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result) { const auto *arguments = std::get_if<EncodableMap>(method_call.arguments()); if (method_call.method_name().compare("getPlatformVersion") == 0) { } else if (method_call.method_name().compare("setLicense") == 0) { } else if (method_call.method_name().compare("decodeFile") == 0) { } else if (method_call.method_name().compare("decodeFileBytes") == 0) { } else if (method_call.method_name().compare("decodeImageBuffer") == 0) { } else { result->NotImplemented(); } } }
獲取參數,并轉換成C++類型:string
,int
,vector<unsigned char>
:
std::string filename; auto filename_it = arguments->find(EncodableValue("filename")); if (filename_it != arguments->end()) { filename = std::get<std::string>(filename_it->second); } std::vector<unsigned char> bytes; auto bytes_it = arguments->find(EncodableValue("bytes")); if (bytes_it != arguments->end()) { bytes = std::get<vector<unsigned char>>(bytes_it->second); } int width = 0; auto width_it = arguments->find(EncodableValue("width")); if (width_it != arguments->end()) { width = std::get<int>(width_it->second); }
返回的結果需要封裝成Flutter定義的類型:
EncodableList results; result->Success(results);
接下來在barcode_manager.h
中實現解碼和結果封裝。
這里定義三個解碼接口:
EncodableList DecodeFile(const char * filename) { EncodableList out; int ret = reader->DecodeFile(filename, ""); if (ret == DBRERR_FILE_NOT_FOUND) { printf("Error code %d. %s\n", ret, CBarcodeReader::GetErrorString(ret)); return out; } return WrapResults(); } EncodableList DecodeFileBytes(const unsigned char * bytes, int size) { reader->DecodeFileInMemory(bytes, size, ""); return WrapResults(); } EncodableList DecodeImageBuffer(const unsigned char * buffer, int width, int height, int stride, int format) { ImagePixelFormat pixelFormat = IPF_BGR_888; switch(format) { case 0: pixelFormat = IPF_GRAYSCALED; break; case 1: pixelFormat = IPF_ARGB_8888; break; } reader->DecodeBuffer(buffer, width, height, stride, pixelFormat, ""); return WrapResults(); }
獲取解碼結果,并封裝到Flutter的map
和list
中:
EncodableList WrapResults() { EncodableList out; TextResultArray *results = NULL; reader->GetAllTextResults(&results); if (results->resultsCount == 0) { printf("No barcode found.\n"); CBarcodeReader::FreeTextResults(&results); } for (int index = 0; index < results->resultsCount; index++) { EncodableMap map; map[EncodableValue("format")] = results->results[index]->barcodeFormatString; map[EncodableValue("text")] = results->results[index]->barcodeText; map[EncodableValue("x1")] = results->results[index]->localizationResult->x1; map[EncodableValue("y1")] = results->results[index]->localizationResult->y1; map[EncodableValue("x2")] = results->results[index]->localizationResult->x2; map[EncodableValue("y2")] = results->results[index]->localizationResult->y2; map[EncodableValue("x3")] = results->results[index]->localizationResult->x3; map[EncodableValue("y3")] = results->results[index]->localizationResult->y3; map[EncodableValue("x4")] = results->results[index]->localizationResult->x4; map[EncodableValue("y4")] = results->results[index]->localizationResult->y4; out.push_back(map); } CBarcodeReader::FreeTextResults(&results); return out; }
到此,用于Windows插件的C++代碼已經完成。最后一步就是配置CMakeLists.txt
文件。
鏈接C++庫:
link_directories("${PROJECT_SOURCE_DIR}/lib/") target_link_libraries(${PLUGIN_NAME} PRIVATE flutter flutter_wrapper_plugin "DBRx64")
打包動態鏈接庫:
set(flutter_barcode_sdk_bundled_libraries "${PROJECT_SOURCE_DIR}/bin/" PARENT_SCOPE )
這步很重要。如果沒有打包進去,應用程序會因為缺少DLL無法運行。
有了插件就可以快速實現桌面掃碼應用。
創建一個新工程,并在pubspec.yaml
中添加依賴:
dependencies: flutter: sdk: flutter flutter_barcode_sdk:
創建SDK對象:
class _DesktopState extends State<Desktop> { String _platformVersion = 'Unknown'; final _controller = TextEditingController(); String _barcodeResults = ''; FlutterBarcodeSdk _barcodeReader; bool _isValid = false; String _file = ''; @override void initState() { super.initState(); initPlatformState(); initBarcodeSDK(); } Future<void> initBarcodeSDK() async { _barcodeReader = FlutterBarcodeSdk(); // Get 30-day FREEE trial license from https://www.dynamsoft.com/customer/license/trialLicense?product=dbr await _barcodeReader.setLicense('LICENSE-KEY'); } }
使用TextField
,Image
,MaterialButton
和Text
構建UI:
@override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: const Text('Dynamsoft Barcode Reader'), ), body: Column(children: [ Container( height: 100, child: Row(children: <Widget>[ Text( _platformVersion, style: TextStyle(fontSize: 14, color: Colors.black), ) ]), ), TextField( controller: _controller, decoration: InputDecoration( labelText: 'Input an image path', errorText: _isValid ? null : 'File not exists', ), ), Expanded( child: SingleChildScrollView( child: Column( children: [ getDefaultImage(), Text( _barcodeResults, style: TextStyle(fontSize: 14, color: Colors.black), ), ], ), ), ), Container( height: 100, child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: <Widget>[ MaterialButton( child: Text('Decode Barcode'), textColor: Colors.white, color: Colors.blue, onPressed: () async { if (_controller.text.isEmpty) { setState(() { _isValid = false; _barcodeResults = ''; _file = ''; }); return; } File file = File(_controller.text); if (!file.existsSync()) { setState(() { _isValid = false; _barcodeResults = ''; _file = ''; }); return; } else { setState(() { _isValid = true; _file = _controller.text; }); } Uint8List bytes = await file.readAsBytes(); List<BarcodeResult> results = await _barcodeReader.decodeFileBytes(bytes); setState(() { _barcodeResults = getBarcodeResults(results); }); }), ]), ), ])), ); }
圖片默認顯示資源包中的圖。如果輸入的圖片有效,顯示輸入的圖片:
Widget getDefaultImage() { if (_controller.text.isEmpty || !_isValid) { return Image.asset('images/default.png'); } else { return Image.file(File(_file)); } }
要使用資源圖片,需要在pubspec.yaml
中添加:
flutter: assets: - images/default.png
最后運行程序:
flutter run -d windows
https://github.com/yushulx/flutter_barcode_sdk
到此,關于“如何使用C++實現Flutter Windows插件”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。