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);
// ---------->>>>>>>>>> 调用 onCreate
if (!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.cc
FlutterViewController::FlutterViewController(int width,
int height,
const DartProject& project) {
engine_ = std::make_unique<FlutterEngine>(project);
// ---------->>>>>>>>>> 调用 FlutterDesktopViewControllerCreate
controller_ = 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) {
// ---------->>>>>>>>>> 调用 CreateViewController
return 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.h
FlutterWindowsEngine::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 的函数指针是: FlutterEngineRun
auto 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.cc
FlutterEngineResult 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;
}
// ---------->>>>>>>>>> 调用 FlutterEngineRunInitialized
return 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::RunEngine
shell_->RunEngine(std::move(run_configuration_));
return true;
}
// \engine-main\shell\common\shell.cc
void Shell::RunEngine(RunConfiguration run_configuration) {
// ---------->>>>>>>>>> 调用 Shell::RunEngine
RunEngine(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.cc
Engine::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();
#endif
UpdateAssetManager(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::LaunchRootIsolate
if (!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.cc
bool 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::CreateRunningRootIsolate
auto 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.cc
std::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::RunFromLibrary
if (!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,就默认为 main
auto 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中的 _runMain
if (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_calls
if (userMainFunction is _ListStringArgFunction) {
userMainFunction(args);
} else {
userMainFunction(); // ignore: avoid_dynamic_calls
}
}, null);
}