当前位置: 首页 > news >正文

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 系统管理与监控&#xff1a;日志管理 1. 日志管理概述 日志文件是系统在运行过程中记录的各种信息&#xff0c;它们是系统管理员排查问题、监控系统健康状况的重要工具。在 Linux 系统中&#xff0c;日志涵盖了系统事件、内核信息、用户操作、软件服务和应用程序等内容…...

VulhubDC-4靶机详解

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

[数据集][目标检测]烟叶病害检测数据集VOC+YOLO格式612张3类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;612 标注数量(xml文件个数)&#xff1a;612 标注数量(txt文件个数)&#xff1a;612 标注类别…...

Sapiens——人类视觉大模型的基础

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

《深度学习》【项目】 OpenCV 身份证号识别

目录 一、项目实施 1、自定义函数 2、定位模版图像中的数字 1&#xff09;模版图二值化处理 运行结果&#xff1a; 2&#xff09;展示所有数字 运行结果&#xff1a; 3、识别身份证号 1&#xff09;灰度图、二值化图展示 运行结果 2&#xff09;定位身份证号每一个数…...

机器学习实战—天猫用户重复购买预测

目录 背景 数据集 用户画像数据 用户行为日志数据 训练数据 测试数据 提交数据 其它数据 数据探索 导入依赖库 读取数据 查看数据信息 缺失值分析 数据分布 复购因素分析 特征工程 模型训练 模型验证 背景 商家有时会在特定日期,例如节礼日(Boxing-day),黑…...

一款rust语言AI神器cursor在ubuntu环境下的安装启动教程

虽然cursor目前只支持英文但是它强大的代码联想能力以及问答能力&#xff0c;可以高效的提高编码效率。 如下步骤所有的前提是你的ubuntu上面已经安装了vscode以及其必须的extensions。 1 下载 到官网https://www.cursor.com下载指定版本的软件。 下载到本地以后会生成如下软…...

【C#生态园】发现C#中的数据科学魔法:6款不可错过的库详解

探索C#中的数据科学与机器学习&#xff1a;6个强大库解析 前言 在数据科学和机器学习领域&#xff0c;Python一直占据着主导地位&#xff0c;然而对于习惯使用C#编程语言的开发人员来说&#xff0c;寻找适用于C#的数据科学库一直是一个挑战。本文将介绍几个流行的用于C#的数据…...

导入neo4j数据CSV文件及csv整理demo示例

Neo4j导入CSV文件&#xff08;实体和关系&#xff09;_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解决办法

一个程序运行多个图&#xff0c;plt.show()一次只弹出一个独立窗口&#xff0c;必须关掉一个才能显示下一张图&#xff0c;想找sciview却发现找不到&#xff0c;本来以为是新版pycharm的问题&#xff0c;后来才发现是community版根本没有sciview…不想换专业版了&#xff0c;研…...

PL/SQL程序设计入门

PL/SQL程序设计 PL/SQL起步鼻祖&#xff1a;hello World语法分析声明部分举例 应用举例 PL/SQL 起步鼻祖&#xff1a;hello World 先举个例子&#xff0c;用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()&#xff0c;类似 python 的 range() &#xff0c;创建一个一维…...

自动化测试框架设计核心理念——关键字驱动

很多人在接触自动化测试时&#xff0c;都会听到关键字驱动这样的一个概念&#xff0c;但是在研究时却有些不太清楚这种驱动模式的设计及实现到底该如何着手去做。 关键字驱动&#xff0c;作为一种自动化测试框架的设计形式&#xff0c;在很早的时候就已经有提及过了。它的基本…...

GO GIN SSE DEMO

文章目录 接口描述&#xff1a;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 中路由跳转之前&#xff0c;需要先将路由声明在 Stack 中<Stack.Navigator initialRouteNameDetails> <Stack.Screen nameDetails /> </Stack.N…...

Linux环境基础开发工具---vim

1.快速的介绍一下vim vim是一款多模式的编辑器&#xff0c;里面有很多子命令&#xff0c;来实现代码编写操作。 2.vim的模式 vim一共有三种模式&#xff1a;底行模式&#xff0c;命令模式&#xff0c;插入模式。 2.1vim模式之间的切换 2.2 谈论常见的模式---命令模式&#xf…...

python AssertionError: Torch not compiled with CUDA enabled

查看&#xff1a;torch import torch# 输出带CPU&#xff0c;表示torch是CPU版本的 print(ftorch的版本是&#xff1a;{torch.__version__}) # print(ftorch是否能使用cuda&#xff1a;{torch.cuda.is_available()}) 修改一下代码&#xff0c;将cuda改成cpu 最后运行正常&…...

Pandas的入门操作-Series对象

Pandas的数据结构 Series对象 class pandas.Series(dataNone, indexNone) data参数 含义&#xff1a;data是Series构造函数中最主要的参数&#xff0c;它用来指定要存储在Series中的数据。 数据类型&#xff1a;data可以是多种数据类型&#xff0c;例如&#xff1a; Python 列…...

自然语言处理系列六十八》搜索引擎项目实战》搜索引擎系统架构设计

注&#xff1a;此文章内容均节选自充电了么创始人&#xff0c;CEO兼CTO陈敬雷老师的新书《自然语言处理原理与实战》&#xff08;人工智能科学与技术丛书&#xff09;【陈敬雷编著】【清华大学出版社】 文章目录 自然语言处理系列六十八搜索引擎项目实战》搜索引擎系统架构设计…...

H5依赖安装

依赖安装 git和sourceTree编辑器使用vscode下载nvm 和nodejs git和sourceTree 使用 ssh-keygen -t rsa 进行密钥获取 git下载地址&#xff1a;https://git-scm.com/ sourceTree下载地址&#xff1a;https://www.sourcetreeapp.com/ 编辑器使用vscode 最新版网址&#xff1a;…...

MatchRFG:引领MemeCoin潮流,探索无限增长潜力

Meme币无疑是本轮牛市最热闹的赛道&#xff0c;而围绕Meme币的讨论话题基本都集中在价格炒作上。似乎人们习惯性地认为&#xff0c;Meme币的创造和成长往往与真正的价值无关。热炒过后&#xff0c;价格能否通过共识转化为价值&#xff0c;也正是许多Meme币在热潮冷却后的主要成…...

2024/9/18 模型的存储与读取

一、模型的存储与读取 主要涉及到torch.save和torch.load函数 新建两个python文件&#xff1a; 1.在model_save文件中保存模型(方式一)和模型参数(方式二) 2.在model_load文件中读取模型(方式一)和模型参数并装载模型(方式二)...

在 fnOS上安装 KVM 虚拟化,并使用 Cockpit 网页管理虚拟机

在fnOS系统上安装 KVM 虚拟化&#xff0c;并使用 Cockpit 进行网页管理&#xff0c;可以按照以下步骤进行&#xff1a; 1. 安装 KVM虚拟化组件 首先&#xff0c;更新软件列表和系统包&#xff1a; sudo apt update && sudo apt upgrade -y 安装 KVM 及相关工具软件&…...

VUE实现刻度尺进度条

一、如下图所示效果&#xff1a; 运行后入下图所示效果&#xff1a; 实现原理是用div画图并动态改变进度&#xff0c; 二、div源码 <div style"width: 100%;"><div class"sdg_title" style"height: 35px;"><!--对话组[{{ dialo…...

ZYNQ FPGA自学笔记~点亮LED

一 ZYNQ FPGA简介 ZYNQ FPGA主要特点是包含了完整的ARM处理系统&#xff0c;内部包含了内存控制器和大量的外设&#xff0c;且可独立于可编程逻辑单元&#xff0c;下图中的ARM内核为 ARM Cortex™-A9&#xff0c;ZYNQ FPGA包含两大功能块&#xff0c;处理系统Processing System…...

攻击者如何在日常网络资源中隐藏恶意软件

近二十年来&#xff0c;安全 Web 网关 (SWG) 一直在监控网络流量&#xff0c;以检测恶意软件、阻止恶意网站并保护企业免受基于 Web 的威胁。 然而&#xff0c;攻击者已经找到了许多绕过这些防御措施的方法&#xff0c;SquareX的安全研究人员对此进行了记录。 最危险的策略之…...

《深度学习》深度学习 框架、流程解析、动态展示及推导

目录 一、深度学习 1、什么是深度学习 2、特点 3、神经网络构造 1&#xff09;单层神经元 • 推导 • 示例 2&#xff09;多层神经网络 3&#xff09;小结 4、感知器 神经网络的本质 5、多层感知器 6、动态图像示例 1&#xff09;一个神经元 相当于下列状态&…...

“中秋快乐”文字横幅的MATLAB代码生成

中秋快乐呀朋友们&#xff01;&#xff01;&#xff01; 给大家带来一个好玩的代码&#xff0c;能够生成“中秋快乐”的横幅文字&#xff0c;比较简单&#xff0c;当然你也可以根据自己的需求去更改文字和背景&#xff0c;废话不多说&#xff0c;直接展示。 文字会一直闪烁&…...