久久久精品网站,成人伊人网,色吧av色av,亚洲AV永久无码精品秋霞电影影院

win10 桌面 移動(dòng)

前沿拓展:

win10 桌面 移動(dòng)

Windows 10的多桌面設(shè)計(jì)讓用戶更加方便的對(duì)任務(wù)進(jìn)行分類管理,使得工作更加井然有序。但是很多用戶可能還不熟悉Windows 10的這個(gè)多桌面設(shè)計(jì),如果想在在不同桌面之間的窗口互相切換,該如何**作呢? 方法很簡(jiǎn)單,具體**作和步驟如下: 1、先轉(zhuǎn)到待移動(dòng)窗口的桌面 2、點(diǎn)擊“任務(wù)視圖”按鈕或者按Win+Tab,右鍵單擊希望移動(dòng)擇目標(biāo)桌面后單擊相應(yīng)編話甚還號(hào)。 注意:Windows 10的

上述是一個(gè)登錄模塊的例子,Module 作為基類,定義了模塊的一些生命周期方法。LoginModule是對(duì)外公開的業(yè)務(wù)接口,里面僅包含外部會(huì)用到的和登錄業(yè)務(wù)相關(guān)的方法。LoginModuleImplV1類是登錄邏輯的具體實(shí)現(xiàn),不對(duì)外公開,里面的私有成員變量和方法對(duì)外部是隱藏的,同時(shí)實(shí)現(xiàn)了Module和LoginModule的接口。Provider用于創(chuàng)建和管理Module實(shí)例。這里采用的思路是,底層模塊和模塊之間,上層和底層之間只依賴接口頭文件,頭文件內(nèi)包含有限的需要對(duì)外暴露的接口。通過(guò)XModule這個(gè)框架,將實(shí)現(xiàn)和接口進(jìn)行分離。為了將接口和實(shí)現(xiàn)分離,用到了 pimpl (Pointer to Implementation) 的理念,將對(duì)象的實(shí)現(xiàn)細(xì)節(jié)隱藏在指針背后。LoginModule接口負(fù)責(zé)定義對(duì)外公開的API,LoginModuleImplV1類負(fù)責(zé)定義LoginModule的具體實(shí)現(xiàn),也就是調(diào)用的指針實(shí)際指向的對(duì)象。調(diào)用方只能知道LoginModule中公開的API,而無(wú)法知道LoginModuleImplV1的實(shí)現(xiàn)細(xì)節(jié),可以降低調(diào)用方的使用門檻,也可以降低錯(cuò)誤使用的可能性。pimpl不僅解除了接口和實(shí)現(xiàn)之間的耦合關(guān)系,還可以降低文件間的編譯依賴關(guān)系,起到“編譯防火墻”的作用,可以提高一定的編譯效率。

// LoginModuleProvider 通過(guò)宏自動(dòng)生成X_MODULE_PROVIDER_DEFINE_SINGLE(LoginModule, MIN_VERSION, MAX_VERSION);// LoginModuleImplV1Provider 通過(guò)宏自動(dòng)生成X_MODULE_DEFINE_SECONDARY_PROVIDER(LoginModuleImplV1, LoginModule);

XModule的模版開發(fā)方式,會(huì)增加很多類文件,為了方便,通過(guò)宏來(lái)控制Provider類的自動(dòng)生成。其中MIN_VERSION和MAX_VERSION是該Module接口能支持的最小和最大的版本范圍,可以限制后期dll插件化加載時(shí),不加載在版本之外的dll,避免產(chǎn)生沖突和錯(cuò)誤,目前Provider的GetVersion使用的是MAX_VERSION。

// 由 X_MODULE_DEFINE_SECONDARY_PROVIDER 宏自動(dòng)生成class DLLEXPORT LoginModuleImplV1Provider : public LoginModuleProvider {public: LoginModule* Create() const { LoginModuleImplV1* p = new LoginModuleImplV1(); ((Module*)p)->OnCreate();return p; } };

LoginModuleImplV1Provider可以通過(guò)調(diào)用Create方法拿到對(duì)應(yīng)的LoginModuleImplV1實(shí)例。

x_module::ModuleCenter* module_center = x_module::ModuleCenter::GetInstance();module_center->AcceptProviderType<LoginModuleProvider>();

ModuleCenter是所有Module的管理類,先通過(guò)x_module::ModuleCenter::GetInstance()拿到ModuleCenter的實(shí)例,它是一個(gè)跨dll的單例。第二要用之前的LoginModuleProvider去注冊(cè)一個(gè)Module類型到ModuleCenter中。LoginModuleProvider中定義了支持的Module類型,以及最小版本和最大版本,如果后續(xù)掃描到的dll中提供的對(duì)應(yīng)類型的Provider中GetVersion返回的值不在最大版本和最小版本之間,那么就不會(huì)被允許加載進(jìn)來(lái)。

module_center->AddProvider(new LoginModuleImplV1Provider());

通過(guò)這種方式,可以將LoginModuleImplV1Provider注冊(cè)到ModuleCenter中,第二創(chuàng)建并管理LoginModuleImplV1的實(shí)例。但是這樣就顯式地依賴了LoginModuleImplV1Provider,違反了前面說(shuō)過(guò)的依賴倒置原則,對(duì)開閉原則也不友好,因?yàn)檫@樣就只能通過(guò)修改代碼來(lái)實(shí)現(xiàn)擴(kuò)展了。

#include <x_module/connector.h>#include “login_module/login_module_impl.h”X_MODULE_CONNECTORbool XModuleConnect(x_module::Owner& owner) { owner.add(new LoginModuleImplV1Provider());return true;}

為了在加載dll時(shí),來(lái)注冊(cè)Provider,增加了一個(gè)connector.cc,添加一個(gè)XModuleConnect方法,讓dll被加載之后,能夠找到XModuleConnect這個(gè)符號(hào)方法,并進(jìn)行調(diào)用,在XModuleConnect被調(diào)用的時(shí)候,會(huì)調(diào)用AddProvider將Provider進(jìn)行注冊(cè)。

std::string path = GetProgramDir();module_center->Install(path, “login_module”);

由于目前l(fā)ogin_module.dll是直接放在exe同目錄的,所以這里直接獲取了一下exe絕對(duì)路徑,第二調(diào)用Install方法,將路徑和dll名login_module傳入進(jìn)去,這樣就完成了注冊(cè)。

auto* p_login_module = module_center->ModuleFromProtocol<LoginModule, LoginModuleProvider>();if (p_login_module == ptr) { (*move_result)->Error(“-100”, “login module 為空”);return;}bool islogin = p_login_module->IsLogin();

在使用時(shí),只需要LoginModule和LoginModuleProvider這兩個(gè)抽象,就能獲取真實(shí)的LoginModuleImplV1這個(gè)實(shí)例,調(diào)用方僅需關(guān)心LoginModule所公開的API,完全屏蔽了對(duì)實(shí)現(xiàn)的依賴。后續(xù)底層擴(kuò)展成了LoginModuleImplV2,只要LoginModule的公開API不變,對(duì)上層是無(wú)感知的。這種方式完全遵循了前面提到的設(shè)計(jì)原則,對(duì)團(tuán)隊(duì)內(nèi)的多人維護(hù)以及后續(xù)的更新迭代都帶來(lái)了穩(wěn)定的保障。

基于vcpkg的C++依賴管理

模塊拆分之后,帶來(lái)的副作用就是依賴管理會(huì)變得更加復(fù)雜,到C++這邊就是CMakeLists的膨脹。從移動(dòng)端的角度來(lái)看這個(gè)問(wèn)題,Android可以通過(guò)Gradle來(lái)管理依賴,依賴庫(kù)構(gòu)建成aar之后上傳到Maven倉(cāng)庫(kù),implementation ‘androidx.recyclerview:recyclerview:1.1.0’像這樣通過(guò)包名、庫(kù)名和版本號(hào)來(lái)依賴具體的庫(kù)。iOS有CocoaPods,通過(guò)添加pod ‘AFNetworking’, ‘~> 2.6’到Podfile來(lái)完成依賴的添加。前端也有NPM這樣的包管理器,所有依賴都在package.json這個(gè)文件中聲明和管理。Flutter側(cè)也可以通過(guò)pubspec來(lái)管理各個(gè)依賴庫(kù)。為了獲得一致的體驗(yàn),解決C++側(cè)依賴管理的痛點(diǎn),我們引入了微軟官方推出的vcpkg,vcpkg的清單模式可以得到類似的體驗(yàn)。

依賴庫(kù)配置

這里以fish-ffi-module模塊為例子,文件結(jié)構(gòu)如下,其中include文件里面是對(duì)外公開的頭文件,src文件包含當(dāng)前庫(kù)內(nèi)部使用的代碼,cmake文件下的config.cmake.in模版文件用于生成xxx-config.cmake的文件,用于被find_package找到。

.├── CMakeLists.txt├── LICENSE├── cmake│ └── config.cmake.in├── include│ └── fish_ffi_module.h├── src│ ├── connector.cc│ ├── fish_ffi_module_impl_v1.cc│ └── fish_ffi_module_impl_v1.h├── vcpkg-configuration.json└── vcpkg.json

vcpkg-configuration.json配置了私有源,后面會(huì)講到。vcpkg.json文件,聲明了當(dāng)前庫(kù)所依賴的其他庫(kù),即vcpkg的依賴清單,其中”dependencies”字段聲明了所使用的依賴名稱。

{“name”: “fish-ffi-module”,“version”: “1.0.0”,“description”: “A fish-ffi module based on fish-ffi-sdk.”,“homepage”: “”,“dependencies”: [“fish-ffi-sdk”,“x-module”,“flutter-sdk” ]}

CMake工程最重要的就是CMakeLists文件了,里面配置了編譯相關(guān)的設(shè)置,添加了相關(guān)的注釋來(lái)幫助理解。

cmake_minimum_required(VERSION 3.15)# 倉(cāng)庫(kù)版本常量,升級(jí)時(shí)修改set(FISH_FFI_MODULE_VERSION “1.0.0”)project(fish-ffi-module VERSION ${FISH_FFI_MODULE_VERSION} DESCRIPTION “A fish-ffi module based on fish-ffi-sdk.” HOMEPAGE_URL “” LANGUAGES CXX)option(BUILD_SHARED_LIBS “Build using shared libraries” ON)# vcpkg清單中添加依賴之后,通過(guò)find_package就能找到find_package(fish-ffi-sdk CONFIG REQUIRED)find_package(flutter-sdk CONFIG REQUIRED)find_package(x-module CONFIG REQUIRED)# configure_package_config_file 生成config要用到include(CMakePackageConfigHelpers)# install 安裝要用到include(GNUInstallDirs)# 當(dāng)前庫(kù)的頭文件和源文件aux_source_directory(include HEADER_LIST)aux_source_directory(src SRC_LIST)add_library(fish-ffi-module SHARED${HEADER_LIST}${SRC_LIST})# 設(shè)置別名add_library(fish-ffi-module::fish-ffi-module ALIAS fish-ffi-module)# 設(shè)置動(dòng)態(tài)庫(kù)導(dǎo)出宏,PRIVATE為編譯時(shí),INTERFACE為運(yùn)行時(shí)if (BUILD_SHARED_LIBS AND WIN32)target_compile_definitions(fish-ffi-module PRIVATE “FISH_FFI_MODULE_EXPORT=__declspec(dllexport)” INTERFACE “FISH_FFI_MODULE_EXPORT=__declspec(dllimport)”)endif ()target_compile_features(fish-ffi-module PUBLIC cxx_std_17)# 添加頭文件target_include_directories(fish-ffi-module PUBLIC lt;BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/> lt;INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)# 鏈接庫(kù)文件target_link_libraries(fish-ffi-module PRIVATE fish-ffi-sdk::fish-ffi-sdk)target_link_libraries(fish-ffi-module PRIVATE flutter-sdk::flutter-sdk)target_link_libraries(fish-ffi-module PRIVATE x-module::x-module)# 基于config.cmake.in的模板生成xxx-config.cmake的文件configure_package_config_file( cmake/config.cmake.in${CMAKE_CURRENT_BINARY_DIR}/fish-ffi-module-config.cmake INSTALL_DESTINATION ${CMAKE_INSTALL_DATADIR}/fish-ffi-module NO_SET_AND_CHECK_MACRO)# 生成xx-config-version.cmake文件write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/fish-ffi-module-config-version.cmake VERSION ${FISH_FFI_MODULE_VERSION} COMPATIBILITY SameMajorVersion)# 將上面生成的兩個(gè)config文件,安裝到share/fish-ffi-module下install( FILES${CMAKE_CURRENT_BINARY_DIR}/fish-ffi-module-config.cmake${CMAKE_CURRENT_BINARY_DIR}/fish-ffi-module-config-version.cmake DESTINATION${CMAKE_INSTALL_DATADIR}/fish-ffi-module)# 安裝頭文件install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})# install targetinstall(TARGETS fish-ffi-moduleEXPORT fish-ffi-module-targets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})# 導(dǎo)出install(EXPORT fish-ffi-module-targets NAMESPACE fish-ffi-module:: DESTINATION ${CMAKE_INSTALL_DATADIR}/fish-ffi-module)

這里面最重要的一點(diǎn)是配置xx-config.cmake和xx-config-version.cmake的生成,vcpkg會(huì)在源碼首次拉下來(lái)的時(shí)候進(jìn)行編譯,編譯完在相應(yīng)庫(kù)的share目錄生成上述兩個(gè)文件,并且在CMake配置階段執(zhí)行,這樣在使用find_package的時(shí)候就能獲取到這個(gè)庫(kù)以及對(duì)應(yīng)版本號(hào)。小編綜合來(lái)說(shuō)一下就是,vcpkg幫助完成了代碼的下載、編譯和配置,第二就可以方便的鏈接三方庫(kù)了。

自定義私有源

私有源的自定義非常簡(jiǎn)單,其實(shí)就是個(gè)Git倉(cāng)庫(kù),push到私有的git托管服務(wù)上即可。只需要將依賴庫(kù)的最新commit信息記錄到這個(gè)倉(cāng)庫(kù)里面,通過(guò)模版化的配置就能完成依賴庫(kù)的發(fā)布。

.├── ports│ ├── fish-ffi-module│ │ ├── portfile.cmake│ │ └── vcpkg.json│ └── x-module│ ├── portfile.cmake│ └── vcpkg.json├── versions│ ├── f-│ │ └── fish-ffi-module.json│ └── x-│ │ └── x-module.json│ └──baseline.json└── LICENSE

vcpkg里面對(duì)依賴庫(kù)的定義叫port,這里定義了兩個(gè)port,分別是fish-ffi-module和x-module。其中的文件說(shuō)明如下:

? portfile.cmake中定義了這個(gè)庫(kù)的git地址、分支、commitId、編譯配置等信息

? vcpkg.json定義了這個(gè)port的依賴以及版本信息,如果有依賴,則會(huì)在編譯這個(gè)庫(kù)之前優(yōu)先編譯依賴。

? versions下的文件按首字母分類,里面定義了version和git-tree的對(duì)應(yīng)關(guān)系。在port新增或更新之后,git-tree需要重新生成,通過(guò)git rev-parse HEAD:ports/x-module來(lái)生成git-tree,第二通過(guò)git commit –amend追加提交到剛剛的commit中。

在需要使用私有源的CMake工程根目錄,添加vcpkg-configuration.json,里面內(nèi)容如下。default-registry為默認(rèn)源,指向官方的地址即可。registries下添加自定義的私有源,再通過(guò)指定packages,表示里面的庫(kù)需要在這個(gè)私有源查找。這樣就完成了私有源的配置。

{“default-registry”: {“kind”: “git”,“repository”: “https://github.com/microsoft/vcpkg”,“baseline”: “f4b262b259145adb2ab0116a390b08642489d32b” },“registries”: [ {“kind”: “git”,“repository”: “xxx.git”,“baseline”: “1ad54586a5a2fadb8c44d3f8f47754e849fc5a38”,“packages”: [ “x-module”, “fish-ffi-sdk”, “fish-ffi-module”] } ] }

在versions文件夾下還有一個(gè)baseline.json的文件,這個(gè)文件主要是設(shè)置基線用的,不像其他的依賴管理工具,vcpkg主要是通過(guò)這個(gè)基線來(lái)設(shè)置當(dāng)前所使用的版本號(hào)的。vcpkg可以勝任依賴管理的相關(guān)工作,綜上所述只是一個(gè)簡(jiǎn)單使用,相比其他平臺(tái)的依賴管理工具略顯繁瑣,除此之外還有很多其他能力,需要到vcpkg.io的官方文檔里面探索了。

小編綜合來(lái)說(shuō)

Flutter應(yīng)用接入Windows平臺(tái),主要遇到的問(wèn)題就是Windows側(cè)的一些能力的提供,需要對(duì)齊Android和iOS的已有能力。因?yàn)槭褂玫氖荂++的開發(fā)語(yǔ)言,對(duì)于移動(dòng)端開發(fā)者并不是那么友好,學(xué)習(xí)曲線相對(duì)會(huì)比較抖。不過(guò)一旦平臺(tái)側(cè)的能力完善之后,又可以回歸到Flutter這個(gè)熟悉的領(lǐng)域了,享受Flutter開發(fā)帶來(lái)的便捷。此外Windows應(yīng)用的開發(fā)不僅僅只是屏幕加大版的移動(dòng)端開發(fā),還包括不同的輸入設(shè)備(鍵盤鼠標(biāo))、交互習(xí)慣、樣式風(fēng)格、**作系統(tǒng)特性等,為了更好的平臺(tái)體驗(yàn),會(huì)帶來(lái)一定的適配成本,這一塊后續(xù)也將持續(xù)投入。

拓展知識(shí):

原創(chuàng)文章,作者:九賢生活小編,如若轉(zhuǎn)載,請(qǐng)注明出處:http://xiesong.cn/119239.html

亚洲男人天堂手机版| 无码成人av在线一区二区| 阿v亚洲天堂网| 欧美日韩国产一区二区三区不卡 | 欧美精品乱人伦久久久久| 伊人情人综合网| www色噜噜| 亚洲无码视频二| 激情综合色五月丁香六月亚洲| 视频一区 亚洲无码| 无码 一区二区三区 水蜜桃| 久久成人国产AV| 少妇人妻在线| 天天天天躁天天爱天天碰2018| 日韩欧美伊人久久大香| 色婷婷六月亚洲婷婷国产| 人妻夜夜爽天天爽三区| 69视频五月| 一区二区在线播放视频| 永久黄网站色视频免费直播| 免费av簧片在看| 国产午夜精品免费一区二区三区| 第四色色五月| 四虎影视亚洲| 播五月欧美视频| 韩国人妻网站| 丰满人妻一级在| 亚洲无码在线播放| xxxx日韩| 大香煮人妻| 久久伊人国产无码| 最好看的2018中文在线观看| 欧美粉嫩| 日韩性av一区| 网色在线观看| 欧美国产亚洲中文字幕| 亚洲国产精品成人va在线观看| 91色偷偷| 四川妇女BBW| 国产精品骚妇女在线| 91亚洲国产图片|