Integrating Flutter Applications on Windows with Modular C++ Architecture and vcpkg Dependency Management
The article explains how to integrate Flutter‑based Windows applications by encapsulating native functionality in a modular C++ XModule framework—using macro‑generated providers, a global ModuleCenter, and CMake‑configured libraries—while managing all third‑party dependencies with vcpkg and private registries to ensure clean architecture and maintainable cross‑platform code.
Windows application development offers many technology choices. Native C#/WPF is niche, C++/Qt is cross‑platform but harder to learn, and JavaScript/CEF/Electron provides a Chromium‑based solution with lower performance. Flutter, since its 2.10 release in February 2022, adds stable Windows support, enabling developers to reuse mobile or web Flutter code on the desktop.
To bring existing Flutter modules to Windows, the project follows a modular approach that isolates responsibilities and reduces coupling. The design adheres to SOLID principles: single responsibility, open‑closed, Liskov substitution, interface segregation, and dependency inversion.
The XModule framework implements this by defining a base Module class, concrete implementations (e.g., LoginModuleImplV1 ), and provider classes generated via macros. Example macro usage:
// LoginModuleProvider generated by macro
X_MODULE_PROVIDER_DEFINE_SINGLE(LoginModule, MIN_VERSION, MAX_VERSION);
// LoginModuleImplV1Provider generated by macro
X_MODULE_DEFINE_SECONDARY_PROVIDER(LoginModuleImplV1, LoginModule);The provider class creates the concrete module instance:
class DLLEXPORT LoginModuleImplV1Provider : public LoginModuleProvider {
public:
LoginModule* Create() const {
LoginModuleImplV1* p = new LoginModuleImplV1();
((Module*)p)->OnCreate();
return p;
}
};Modules are registered with a global ModuleCenter singleton:
x_module::ModuleCenter* module_center = x_module::ModuleCenter::GetInstance();
module_center->AcceptProviderType
();
module_center->AddProvider(new LoginModuleImplV1Provider());A connector function exposes the provider when the DLL is loaded:
bool XModuleConnect(x_module::Owner& owner) {
owner.add(new LoginModuleImplV1Provider());
return true;
}Because modularization introduces many CMake dependencies, the project adopts vcpkg for C++ package management. The vcpkg.json file declares runtime dependencies:
{
"name": "fish-ffi-module",
"version": "1.0.0",
"description": "A fish-ffi module based on fish-ffi-sdk.",
"dependencies": ["fish-ffi-sdk", "x-module", "flutter-sdk"]
}The main CMakeLists.txt configures the library, finds the required packages, and installs the generated *-config.cmake files:
cmake_minimum_required(VERSION 3.15)
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." LANGUAGES CXX)
option(BUILD_SHARED_LIBS "Build using shared libraries" ON)
find_package(fish-ffi-sdk CONFIG REQUIRED)
find_package(flutter-sdk CONFIG REQUIRED)
find_package(x-module CONFIG REQUIRED)
aux_source_directory(include HEADER_LIST)
aux_source_directory(src SRC_LIST)
add_library(fish-ffi-module SHARED ${HEADER_LIST} ${SRC_LIST})
add_library(fish-ffi-module::fish-ffi-module ALIAS fish-ffi-module)
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 $
$
)
target_link_libraries(fish-ffi-module PRIVATE fish-ffi-sdk::fish-ffi-sdk flutter-sdk::flutter-sdk x-module::x-module)
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)
write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/fish-ffi-module-config-version.cmake VERSION ${FISH_FFI_MODULE_VERSION} COMPATIBILITY SameMajorVersion)
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(TARGETS fish-ffi-module EXPORT fish-ffi-module-targets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(EXPORT fish-ffi-module-targets NAMESPACE fish-ffi-module:: DESTINATION ${CMAKE_INSTALL_DATADIR}/fish-ffi-module)Custom private registries are defined in vcpkg-configuration.json , allowing the project to pull internal ports such as x-module and fish-ffi-sdk from a private Git repository.
In summary, integrating Flutter on Windows requires providing native capabilities via C++ plugins, organizing code with a modular XModule framework, and managing third‑party libraries through vcpkg. This approach improves maintainability, enforces clean architecture, and streamlines dependency handling across platforms.
Xianyu Technology
Official account of the Xianyu technology team
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.