Flutter - Win32程序是如何执行main函数
Win32程序的主体结构
int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,_In_ wchar_t *command_line, _In_ int show_command) {// Attach to console when present (e.g., 'flutter run') or create a// new console when running with a debugger.if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) {CreateAndAttachConsole();}// Initialize COM, so that it is available for use in the library and/or// plugins.::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);flutter::DartProject project(L"data");std::vector<std::string> command_line_arguments =GetCommandLineArguments();project.set_dart_entrypoint_arguments(std::move(command_line_arguments));FlutterWindow window(project);Win32Window::Point origin(10, 10);Win32Window::Size size(1280, 720);// ---------->>>>>>>>>> 调用 onCreateif (!window.Create(L"study_common", origin, size)) {return EXIT_FAILURE;}window.SetQuitOnClose(true);::MSG msg;while (::GetMessage(&msg, nullptr, 0, 0)) {::TranslateMessage(&msg);::DispatchMessage(&msg);}::CoUninitialize();return EXIT_SUCCESS;
}
bool FlutterWindow::OnCreate() {if (!Win32Window::OnCreate()) {return false;}RECT frame = GetClientArea();// ---------->>>>>>>>>> 调用 FlutterViewController构造函数flutter_controller_ = std::make_unique<flutter::FlutterViewController>( frame.right - frame.left, frame.bottom - frame.top, project_); if (!flutter_controller_->engine() || !flutter_controller_->view()) {return false;}RegisterPlugins(flutter_controller_->engine());SetChildContent(flutter_controller_->view()->GetNativeWindow());flutter_controller_->engine()->SetNextFrameCallback([&]() {this->Show();});flutter_controller_->ForceRedraw();return true;
}
// \engine-main\shell\platform\windows\client_wrapper\flutter_view_controller.ccFlutterViewController::FlutterViewController(int width,int height,const DartProject& project) {engine_ = std::make_unique<FlutterEngine>(project);// ---------->>>>>>>>>> 调用 FlutterDesktopViewControllerCreatecontroller_ = FlutterDesktopViewControllerCreate(width, height,engine_->RelinquishEngine());if (!controller_) {std::cerr << "Failed to create view controller." << std::endl;return;}view_ = std::make_unique<FlutterView>(FlutterDesktopViewControllerGetView(controller_));
}
// \engine-main\shell\platform\windows\flutter_windows.cc FlutterDesktopViewControllerRef FlutterDesktopViewControllerCreate(int width,int height,FlutterDesktopEngineRef engine) {// ---------->>>>>>>>>> 调用 CreateViewControllerreturn CreateViewController(engine, width, height, /*owns_engine=*/true);
}static FlutterDesktopViewControllerRef CreateViewController(FlutterDesktopEngineRef engine_ref,int width,int height,bool owns_engine) {...省略代码std::unique_ptr<flutter::FlutterWindowsEngine> engine;if (owns_engine) {engine = std::unique_ptr<flutter::FlutterWindowsEngine>(engine_ptr);}std::unique_ptr<flutter::FlutterWindowsView> view =engine_ptr->CreateView(std::move(window_wrapper));if (!view) {return nullptr;}auto controller = std::make_unique<flutter::FlutterWindowsViewController>(std::move(engine), std::move(view));if (!controller->engine()->running()) {// ---------->>>>>>>>>> 调用 FlutterWindowsEngine::Run()if (!controller->engine()->Run()) {return nullptr;}}controller->view()->SendInitialBounds();controller->engine()->UpdateAccessibilityFeatures();return HandleForViewController(controller.release());
}
// \engine-main\shell\platform\windows\flutter_windows_engine.hFlutterWindowsEngine::FlutterWindowsEngine(const FlutterProjectBundle& project,std::shared_ptr<WindowsProcTable> windows_proc_table): project_(std::make_unique<FlutterProjectBundle>(project)),windows_proc_table_(std::move(windows_proc_table)),aot_data_(nullptr, nullptr),lifecycle_manager_(std::make_unique<WindowsLifecycleManager>(this)) {// 省略代码// FlutterEngineGetProcAddresses内部初始化 embedder_api_ 的所有函数指针成员embedder_api_.struct_size = sizeof(FlutterEngineProcTable);FlutterEngineGetProcAddresses(&embedder_api_); plugin_registrar_ = std::make_unique<FlutterDesktopPluginRegistrar>();plugin_registrar_->engine = this;// Check for impeller support.auto& switches = project_->GetSwitches();enable_impeller_ = std::find(switches.begin(), switches.end(),"--enable-impeller=true") != switches.end();
}bool FlutterWindowsEngine::Run() {return Run("");
}bool FlutterWindowsEngine::Run(std::string_view entrypoint) {if (!project_->HasValidPaths()) {FML_LOG(ERROR) << "Missing or unresolvable paths to assets.";return false;}std::string assets_path_string = project_->assets_path().u8string();std::string icu_path_string = project_->icu_path().u8string();if (embedder_api_.RunsAOTCompiledDartCode()) {// LoadAotData 这里初始化embedder_api_的每个成员指针aot_data_ = project_->LoadAotData(embedder_api_); if (!aot_data_) {FML_LOG(ERROR) << "Unable to start engine without AOT data.";return false;}}// 省略代码// argv 中可以控制是否可以开启一些功能。 比如是否开启 impeller功能std::string executable_name = GetExecutableName();std::vector<const char*> argv = {executable_name.c_str()};std::vector<std::string> switches = project_->GetSwitches();std::transform(switches.begin(), switches.end(), std::back_inserter(argv),[](const std::string& arg) -> const char* { return arg.c_str(); });const std::vector<std::string>& entrypoint_args =project_->dart_entrypoint_arguments();std::vector<const char*> entrypoint_argv;std::transform(entrypoint_args.begin(), entrypoint_args.end(),std::back_inserter(entrypoint_argv),[](const std::string& arg) -> const char* { return arg.c_str(); });FlutterProjectArgs args = {};args.struct_size = sizeof(FlutterProjectArgs);args.shutdown_dart_vm_when_done = true;args.assets_path = assets_path_string.c_str();args.icu_data_path = icu_path_string.c_str();args.command_line_argc = static_cast<int>(argv.size());args.command_line_argv = argv.empty() ? nullptr : argv.data();// 如果自定义入口点,就启用自定义入口 (默认是main函数)if (!entrypoint.empty()) {args.custom_dart_entrypoint = entrypoint.data();} else if (!project_->dart_entrypoint().empty()) {args.custom_dart_entrypoint = project_->dart_entrypoint().c_str();}// 传递给dart::main函数的参数args.dart_entrypoint_argc = static_cast<int>(entrypoint_argv.size());args.dart_entrypoint_argv =entrypoint_argv.empty() ? nullptr : entrypoint_argv.data();if (aot_data_) {args.aot_data = aot_data_.get();}// The platform thread creates OpenGL contexts. These// must be released to be used by the engine's threads.FML_DCHECK(!egl_manager_ || !egl_manager_->HasContextCurrent());FlutterRendererConfig renderer_config;if (enable_impeller_) {// Impeller does not support a Software backend. Avoid falling back and// confusing the engine on which renderer is selected.if (!egl_manager_) {FML_LOG(ERROR) << "Could not create surface manager. Impeller backend ""does not support software rendering.";return false;}renderer_config = GetOpenGLRendererConfig();} else {renderer_config =egl_manager_ ? GetOpenGLRendererConfig() : GetSoftwareRendererConfig();}// ---------->>>>>>>>>> embedder_api_.Run 的函数指针是: FlutterEngineRunauto result = embedder_api_.Run(FLUTTER_ENGINE_VERSION, &renderer_config,&args, this, &engine_);if (result != kSuccess || engine_ == nullptr) {FML_LOG(ERROR) << "Failed to start Flutter engine: error " << result;return false;}// 省略代码return true;
}
// \engine-main\shell\platform\embedder\embedder.ccFlutterEngineResult FlutterEngineRun(size_t version,const FlutterRendererConfig* config,const FlutterProjectArgs* args,void* user_data,FLUTTER_API_SYMBOL(FlutterEngine) *engine_out) {auto result =FlutterEngineInitialize(version, config, args, user_data, engine_out);if (result != kSuccess) {return result;}// ---------->>>>>>>>>> 调用 FlutterEngineRunInitializedreturn FlutterEngineRunInitialized(*engine_out);
}FlutterEngineResult FlutterEngineRunInitialized(FLUTTER_API_SYMBOL(FlutterEngine) engine) {if (!engine) {return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");}auto embedder_engine = reinterpret_cast<flutter::EmbedderEngine*>(engine);if (embedder_engine->IsValid()) {return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");}if (!embedder_engine->LaunchShell()) {return LOG_EMBEDDER_ERROR(kInvalidArguments,"Could not launch the engine using supplied ""initialization arguments.");}if (!embedder_engine->NotifyCreated()) {return LOG_EMBEDDER_ERROR(kInternalInconsistency,"Could not create platform view components.");}// ---------->>>>>>>>>> 调用 EmbedderEngine::RunRootIsolate()if (!embedder_engine->RunRootIsolate()) { return LOG_EMBEDDER_ERROR(kInvalidArguments,"Could not run the root isolate of the Flutter application using the ""project arguments specified.");}return kSuccess;
}bool EmbedderEngine::RunRootIsolate() {if (!IsValid() || !run_configuration_.IsValid()) {return false;}// ---------->>>>>>>>>> 调用 Shell::RunEngineshell_->RunEngine(std::move(run_configuration_));return true;
}
// \engine-main\shell\common\shell.ccvoid Shell::RunEngine(RunConfiguration run_configuration) {// ---------->>>>>>>>>> 调用 Shell::RunEngineRunEngine(std::move(run_configuration), nullptr);
}void Shell::RunEngine(RunConfiguration run_configuration,const std::function<void(Engine::RunStatus)>& result_callback) {auto result = [platform_runner = task_runners_.GetPlatformTaskRunner(),result_callback](Engine::RunStatus run_result) {if (!result_callback) {return;}platform_runner->PostTask([result_callback, run_result]() { result_callback(run_result); });};FML_DCHECK(is_set_up_);FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread());fml::TaskRunner::RunNowOrPostTask(task_runners_.GetUITaskRunner(),fml::MakeCopyable([run_configuration = std::move(run_configuration),weak_engine = weak_engine_, result]() mutable {if (!weak_engine) {FML_LOG(ERROR)<< "Could not launch engine with configuration - no engine.";result(Engine::RunStatus::Failure);return;}// ---------->>>>>>>>>> 调用 Engine::Run()auto run_result = weak_engine->Run(std::move(run_configuration));if (run_result == flutter::Engine::RunStatus::Failure) {FML_LOG(ERROR) << "Could not launch engine with configuration.";}result(run_result);}));
}
// \engine-main\shell\common\engine.ccEngine::RunStatus Engine::Run(RunConfiguration configuration) {if (!configuration.IsValid()) {FML_LOG(ERROR) << "Engine run configuration was invalid.";return RunStatus::Failure;}last_entry_point_ = configuration.GetEntrypoint();last_entry_point_library_ = configuration.GetEntrypointLibrary();
#if (FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG)// This is only used to support restart.last_entry_point_args_ = configuration.GetEntrypointArgs();
#endifUpdateAssetManager(configuration.GetAssetManager());if (runtime_controller_->IsRootIsolateRunning()) {return RunStatus::FailureAlreadyRunning;}// If the embedding prefetched the default font manager, then set up the// font manager later in the engine launch process. This makes it less// likely that the setup will need to wait for the prefetch to complete.auto root_isolate_create_callback = [&]() {if (settings_.prefetched_default_font_manager) {SetupDefaultFontManager();}};// ---------->>>>>>>>>> 调用 RuntimeController::LaunchRootIsolateif (!runtime_controller_->LaunchRootIsolate(settings_, //root_isolate_create_callback, //configuration.GetEntrypoint(), //configuration.GetEntrypointLibrary(), //configuration.GetEntrypointArgs(), //configuration.TakeIsolateConfiguration()) //) {return RunStatus::Failure;}auto service_id = runtime_controller_->GetRootIsolateServiceID();if (service_id.has_value()) {std::unique_ptr<PlatformMessage> service_id_message =std::make_unique<flutter::PlatformMessage>(kIsolateChannel, MakeMapping(service_id.value()), nullptr);HandlePlatformMessage(std::move(service_id_message));}return Engine::RunStatus::Success;
}
// \engine-main\runtime\runtime_controller.ccbool RuntimeController::LaunchRootIsolate(const Settings& settings,const fml::closure& root_isolate_create_callback,std::optional<std::string> dart_entrypoint,std::optional<std::string> dart_entrypoint_library,const std::vector<std::string>& dart_entrypoint_args,std::unique_ptr<IsolateConfiguration> isolate_configuration) {if (root_isolate_.lock()) {FML_LOG(ERROR) << "Root isolate was already running.";return false;}// ---------->>>>>>>>>> 调用 DartIsolate::CreateRunningRootIsolateauto strong_root_isolate =DartIsolate::CreateRunningRootIsolate(settings, //isolate_snapshot_, //std::make_unique<PlatformConfiguration>(this), //DartIsolate::Flags{}, //root_isolate_create_callback, //isolate_create_callback_, //isolate_shutdown_callback_, //std::move(dart_entrypoint), //std::move(dart_entrypoint_library), //dart_entrypoint_args, //std::move(isolate_configuration), //context_, //spawning_isolate_.lock().get()) //.lock();if (!strong_root_isolate) {FML_LOG(ERROR) << "Could not create root isolate.";return false;}// Enable platform channels for background isolates.strong_root_isolate->GetIsolateGroupData().SetPlatformMessageHandler(strong_root_isolate->GetRootIsolateToken(),client_.GetPlatformMessageHandler());// The root isolate ivar is weak.root_isolate_ = strong_root_isolate;// Capture by `this` here is safe because the callback is made by the dart// state itself. The isolate (and its Dart state) is owned by this object and// it will be collected before this object.strong_root_isolate->SetReturnCodeCallback([this](uint32_t code) { root_isolate_return_code_ = code; });if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {tonic::DartState::Scope scope(strong_root_isolate);platform_configuration->DidCreateIsolate();if (!FlushRuntimeStateToIsolate()) {FML_DLOG(ERROR) << "Could not set up initial isolate state.";}} else {FML_DCHECK(false) << "RuntimeController created without window binding.";}FML_DCHECK(Dart_CurrentIsolate() == nullptr);client_.OnRootIsolateCreated();return true;
}
// \engine-main\runtime\dart_isolate.ccstd::weak_ptr<DartIsolate> DartIsolate::CreateRunningRootIsolate(const Settings& settings,const fml::RefPtr<const DartSnapshot>& isolate_snapshot,std::unique_ptr<PlatformConfiguration> platform_configuration,Flags isolate_flags,const fml::closure& root_isolate_create_callback,const fml::closure& isolate_create_callback,const fml::closure& isolate_shutdown_callback,std::optional<std::string> dart_entrypoint,std::optional<std::string> dart_entrypoint_library,const std::vector<std::string>& dart_entrypoint_args,std::unique_ptr<IsolateConfiguration> isolate_configuration,const UIDartState::Context& context,const DartIsolate* spawning_isolate) {if (!isolate_snapshot) {FML_LOG(ERROR) << "Invalid isolate snapshot.";return {};}if (!isolate_configuration) {FML_LOG(ERROR) << "Invalid isolate configuration.";return {};}isolate_flags.SetNullSafetyEnabled(isolate_configuration->IsNullSafetyEnabled(*isolate_snapshot));isolate_flags.SetIsDontNeedSafe(isolate_snapshot->IsDontNeedSafe());auto isolate = CreateRootIsolate(settings, //isolate_snapshot, //std::move(platform_configuration), //isolate_flags, //isolate_create_callback, //isolate_shutdown_callback, //context, //spawning_isolate //).lock();// 省略代码// ---------->>>>>>>>>> 调用 DartIsolate::RunFromLibraryif (!isolate->RunFromLibrary(std::move(dart_entrypoint_library), //std::move(dart_entrypoint), //dart_entrypoint_args)) {FML_LOG(ERROR) << "Could not run the run main Dart entrypoint.";return {};}// 省略代码return isolate;
}bool DartIsolate::RunFromLibrary(std::optional<std::string> library_name,std::optional<std::string> entrypoint,const std::vector<std::string>& args) {TRACE_EVENT0("flutter", "DartIsolate::RunFromLibrary");if (phase_ != Phase::Ready) {return false;}tonic::DartState::Scope scope(this);auto library_handle =library_name.has_value() && !library_name.value().empty()? ::Dart_LookupLibrary(tonic::ToDart(library_name.value().c_str())): ::Dart_RootLibrary();// entrypoint_handle 就是 main的函数入口。如果没有指定entrypoint,就默认为 mainauto entrypoint_handle = entrypoint.has_value() && !entrypoint.value().empty()? tonic::ToDart(entrypoint.value().c_str()): tonic::ToDart("main");if (!FindAndInvokeDartPluginRegistrant()) {// TODO(gaaclarke): Remove once the framework PR lands that uses `--source`// to compile the Dart Plugin Registrant// (https://github.com/flutter/flutter/pull/100572).InvokeDartPluginRegistrantIfAvailable(library_handle);}auto user_entrypoint_function =::Dart_GetField(library_handle, entrypoint_handle);auto entrypoint_args = tonic::ToDart(args);// ---------->>>>>>>>>> 调用 dart::main函数if (!InvokeMainEntrypoint(user_entrypoint_function, entrypoint_args)) {return false;}phase_ = Phase::Running;return true;
}[[nodiscard]] static bool InvokeMainEntrypoint(Dart_Handle user_entrypoint_function,Dart_Handle args) {if (tonic::CheckAndHandleError(user_entrypoint_function)) {FML_LOG(ERROR) << "Could not resolve main entrypoint function.";return false;}Dart_Handle start_main_isolate_function =tonic::DartInvokeField(Dart_LookupLibrary(tonic::ToDart("dart:isolate")),"_getStartMainIsolateFunction", {});if (tonic::CheckAndHandleError(start_main_isolate_function)) {FML_LOG(ERROR) << "Could not resolve main entrypoint trampoline.";return false;}// ---------->>>>>>>>>> 调用 dart中的 _runMainif (tonic::CheckAndHandleError(tonic::DartInvokeField(Dart_LookupLibrary(tonic::ToDart("dart:ui")), "_runMain",{start_main_isolate_function, user_entrypoint_function, args}))) {FML_LOG(ERROR) << "Could not invoke the main entrypoint.";return false;}return true;
}// 调试 flutter的windows程序时,
// 会进入到 \flutter\bin\cache\pkg\sky_engine\lib\ui\hooks.dart
@pragma('vm:entry-point')
void _runMain(Function startMainIsolateFunction,Function userMainFunction,List<String> args) {startMainIsolateFunction(() { // ignore: avoid_dynamic_callsif (userMainFunction is _ListStringArgFunction) {userMainFunction(args);} else {userMainFunction(); // ignore: avoid_dynamic_calls}}, null);
}
相关文章:
Flutter - Win32程序是如何执行main函数
Win32程序的主体结构 int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,_In_ wchar_t *command_line, _In_ int show_command) {// Attach to console when present (e.g., flutter run) or create a// new console when running with a debugger.if …...
linux-系统管理与监控-日志管理
Linux 系统管理与监控:日志管理 1. 日志管理概述 日志文件是系统在运行过程中记录的各种信息,它们是系统管理员排查问题、监控系统健康状况的重要工具。在 Linux 系统中,日志涵盖了系统事件、内核信息、用户操作、软件服务和应用程序等内容…...

VulhubDC-4靶机详解
项目地址 https://download.vulnhub.com/dc/DC-4.zip实验过程 将下载好的靶机导入到VMware中,设置网络模式为NAT模式,然后开启靶机虚拟机 使用nmap进行主机发现,获取靶机IP地址 nmap 192.168.47.1-254根据对比可知DC-4的一个ip地址为192.1…...

[数据集][目标检测]烟叶病害检测数据集VOC+YOLO格式612张3类别
数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):612 标注数量(xml文件个数):612 标注数量(txt文件个数):612 标注类别…...

Sapiens——人类视觉大模型的基础
引言 大规模预训练以及随后针对特定任务的语言建模微调取得了显著成功,已将这种方法确立为标准做法。同样, 计算机视觉方法正逐步采用大规模数据进行预训练。LAION5B、Instagram-3.5B、JFT-300M、LVD142M、Visual Genome 和 YFCC100M 等大型数据集的出现…...

《深度学习》【项目】 OpenCV 身份证号识别
目录 一、项目实施 1、自定义函数 2、定位模版图像中的数字 1)模版图二值化处理 运行结果: 2)展示所有数字 运行结果: 3、识别身份证号 1)灰度图、二值化图展示 运行结果 2)定位身份证号每一个数…...
机器学习实战—天猫用户重复购买预测
目录 背景 数据集 用户画像数据 用户行为日志数据 训练数据 测试数据 提交数据 其它数据 数据探索 导入依赖库 读取数据 查看数据信息 缺失值分析 数据分布 复购因素分析 特征工程 模型训练 模型验证 背景 商家有时会在特定日期,例如节礼日(Boxing-day),黑…...

一款rust语言AI神器cursor在ubuntu环境下的安装启动教程
虽然cursor目前只支持英文但是它强大的代码联想能力以及问答能力,可以高效的提高编码效率。 如下步骤所有的前提是你的ubuntu上面已经安装了vscode以及其必须的extensions。 1 下载 到官网https://www.cursor.com下载指定版本的软件。 下载到本地以后会生成如下软…...
【C#生态园】发现C#中的数据科学魔法:6款不可错过的库详解
探索C#中的数据科学与机器学习:6个强大库解析 前言 在数据科学和机器学习领域,Python一直占据着主导地位,然而对于习惯使用C#编程语言的开发人员来说,寻找适用于C#的数据科学库一直是一个挑战。本文将介绍几个流行的用于C#的数据…...
导入neo4j数据CSV文件及csv整理demo示例
Neo4j导入CSV文件(实体和关系)_neo4j导入csv关系-CSDN博客 https://blog.csdn.net/m0_69483514/article/details/131296060?spm1001.2101.3001.6661.1&utm_mediumdistribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ER…...
bug | pycharm社区版无sciview解决办法
一个程序运行多个图,plt.show()一次只弹出一个独立窗口,必须关掉一个才能显示下一张图,想找sciview却发现找不到,本来以为是新版pycharm的问题,后来才发现是community版根本没有sciview…不想换专业版了,研…...
PL/SQL程序设计入门
PL/SQL程序设计 PL/SQL起步鼻祖:hello World语法分析声明部分举例 应用举例 PL/SQL 起步鼻祖:hello World 先举个例子,用PL/SQL打印输出hello world declarev_string varchar2(20); beginv_string:hello world;dbms_output.put_line(v_str…...
一、Numpy入门
Numpy入门 前言一、numpy简介二、Numpy的ndarray属性2.1. 直接用 .属性的方法实现2.2. 直接函数的方法实现 三、Numpy的ndarray的创建3.1. ndarray介绍3.2. 数组形式3.3. zeros()、ones() 、 empty()3.4. arange(),类似 python 的 range() ,创建一个一维…...

自动化测试框架设计核心理念——关键字驱动
很多人在接触自动化测试时,都会听到关键字驱动这样的一个概念,但是在研究时却有些不太清楚这种驱动模式的设计及实现到底该如何着手去做。 关键字驱动,作为一种自动化测试框架的设计形式,在很早的时候就已经有提及过了。它的基本…...
GO GIN SSE DEMO
文章目录 接口描述:1.1 /events/time - 时间流1.2 /events/numbers - 数字流 2. 用户管理接口2.1 /user/:id - 获取用户信息2.2 /user - 创建用户 项目结构1. main.go2. 创建 handlers/event_time.go3. 创建 handlers/event_number.go4. handlers/user.go5. 运行服务…...
GEE教程:1950-2023年ECMWF数据中积雪的长时序统计分析
目录 简介 数据 函数 millis() Arguments: Returns: Long 代码 结果 简介 1950-2023年ECMWF数据中积雪的长时序统计分析 数据 ECMWF/ERA5_LAND/DAILY_AGGR是由欧洲中期天气预报中心(ECMWF)提供的数据集。它是一个格网数据集,包含从ERA5-Land再分析数据集中得出的…...
【React Native】路由和导航
RN 中的路由是通过 React Navigation 组件来完成的 Stack 路由导航RN 中默认没有类似浏览器的 history 对象在 RN 中路由跳转之前,需要先将路由声明在 Stack 中<Stack.Navigator initialRouteNameDetails> <Stack.Screen nameDetails /> </Stack.N…...

Linux环境基础开发工具---vim
1.快速的介绍一下vim vim是一款多模式的编辑器,里面有很多子命令,来实现代码编写操作。 2.vim的模式 vim一共有三种模式:底行模式,命令模式,插入模式。 2.1vim模式之间的切换 2.2 谈论常见的模式---命令模式…...

python AssertionError: Torch not compiled with CUDA enabled
查看:torch import torch# 输出带CPU,表示torch是CPU版本的 print(ftorch的版本是:{torch.__version__}) # print(ftorch是否能使用cuda:{torch.cuda.is_available()}) 修改一下代码,将cuda改成cpu 最后运行正常&…...

Pandas的入门操作-Series对象
Pandas的数据结构 Series对象 class pandas.Series(dataNone, indexNone) data参数 含义:data是Series构造函数中最主要的参数,它用来指定要存储在Series中的数据。 数据类型:data可以是多种数据类型,例如: Python 列…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?
在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...

Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...

多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...

Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...