Flutter - Win32程序是如何执行main函数

ops/2024/11/15 0:50:38/

 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);
}


http://www.ppmy.cn/ops/113303.html

相关文章

Linux 防火墙:Firewalld 常用命令行操作命令

firewalld命令行操作管理 按增删改查分类&#xff0c;前面加上 firewall-cmd &#xff1a; ### 查询操作--get-default-zone 查看当前默认区域 --get-zones 查看所有可用的区域 --get-active-zones …

科技赋能司法:易保全如何重塑法律文书签署与庭审流程

在这个数字化飞速发展的时代&#xff0c;司法领域也迎来了前所未有的变革。随着人工智能、区块链与互联网技术的深度融合&#xff0c;正以前所未有的力量变革着司法服务的格局。 易保全通过将“区块链人工智能互联网司法”相融合&#xff0c;推动公证系统逐步迈向智能化、高效…

C++学习笔记 —— 内存分配 new

//创建数值 int *pi new int; //pi指向动态分配的&#xff0c;未初始化的无名对象 delete pi; int *pi new int(10); //pi指向动态分配的&#xff0c;初始化10 delete pi;//创建数组 int *a new int[5]; //创建一个数组&#xff0c;未初始化数值 delete []a; // new 和 de…

二叉树进阶--AVL树

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 二叉树进阶--AVL树 收录于专栏 [C进阶学习] 本专栏旨在分享学习C的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目录 前提提示: 1 AVL树的…

Leetcode Hot 100刷题记录 -Day17(搜索二维矩阵II)

搜索二维矩阵II 问题描述&#xff1a; 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a; 每行的元素从左到右升序排列。每列的元素从上到下升序排列。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,4,7,11,15],[2,5,8,…

win/mac常用命令

这里写目录标题 windows&#xff08;powershell&#xff09;mac windows&#xff08;powershell&#xff09; Get-ChildItem | ForEach-Object { $_.Name }&#xff1a;打印当前目录中所有文件的名字Get-ChildItem | ForEach-Object { $_.Name } > file_list.txt&#xff1…

防火墙--NAT技术,基于源NAT,NAT服务器,双向NAT

文章目录 防火墙--NAT技术一、基于源NAT**方式**&#xff1a;NAT No-PATNAPT出接口地址方式Smart NAT三元组 NAT 二、基于服务器的NAT多出口场景下的NAT Server 三、双向NAT 防火墙–NAT技术 基于源NAT&#xff1a;用于将内部网络的私有IP地址转换为公共IP地址&#xff0c;以便…

Python | Leetcode Python题解之第419题棋盘上的战舰

题目&#xff1a; 题解&#xff1a; class Solution:def countBattleships(self, board: List[List[str]]) -> int:return sum(ch X and not (i > 0 and board[i - 1][j] X or j > 0 and board[i][j - 1] X)for i, row in enumerate(board) for j, ch in enumerat…