7AA7 / 开放文档
返回首页

编译规范

更新于 2026-10-12
未按本规范编译出来的 DLL,主程序会直接拒绝加载。

一、编译环境与依赖

项目硬性要求
Qt 版本必须与主程序完全一致(Qt 6.11.1,套件目录 6.11.1/mingw_64)
编译器MinGW-w64 GCC 13.1(win32 线程模型, SEH)64-bit;禁止 MSVC
目标架构x64 仅此一种;ARM64 客户端不提供插件市场
编译模式Release + x64(Debug / 32-bit 一律拒绝)
Qt 链接方式动态链接 Qt,禁止静态编译
C++ 标准C++17 或更高
字符集Unicode(_UNICODE,Qt 默认)
为什么必须完全一致:QString / QWidget 等 Qt 对象跨 DLL 边界安全传递的前提,是双方 Qt 大版本、小版本与工具链完全一致,否则会出现虚表不匹配、堆分配器不同、布局错位等崩溃。 历史教训(2.2.6 事故):商店版主程序曾误用 MSVC,而插件按 MinGW 编译,LoadLibrary 直接返回 126(找不到 libgcc_s_seh-1.dll)。自 2.2.7.0 起,商店 x64 版与官网 EXE 版统一为 MinGW 主路线,主程序在 QPluginLoader 之前做 PE 工具链预检。

二、工程搭建最小模板

cmake
cmake_minimum_required(VERSION 3.20)
project(DemoPlugin LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)

# 指向与主程序完全一致的 Qt 安装目录(请自行修改)
set(CMAKE_PREFIX_PATH "E:/Qt/6.11.1/mingw_64")

find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)

qt_add_plugin(DemoPlugin
    SHARED
    demo/DemoPlugin.h
    demo/DemoPlugin.cpp
    demo/DemoPlugin.json
)

target_include_directories(DemoPlugin PRIVATE
    ${CMAKE_CURRENT_SOURCE_DIR}/include
)

target_link_libraries(DemoPlugin PRIVATE
    Qt6::Core
    Qt6::Gui
    Qt6::Widgets
)

三、命令行构建

前置:MinGW 13.1(mingw1310_64)、Ninja、CMake 三者加入 PATH。

powershell
cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release `
      -DCMAKE_PREFIX_PATH="E:/Qt/6.11.1/mingw_64"
cmake --build build

验证产物工具链:g++ -v 应为 13.1,目标 x86_64-w64-mingw32;DLL 导入表应能看到 libgcc_s_seh-1.dll / libstdc++-6.dll(由主程序统一部署,不要随插件分发)。

四、编译自检 Checklist

逐条对照,任何一条不满足加载都会失败:

#检查项不满足的报错码
1DLL 可被 QLibrary::isLibrary() 识别FileCorrupted
2导出 qt_plugin_instance / qt_plugin_query_metadataNotAQtPlugin
3元数据 IID 为 com.7aa7.toolbox.I7AA7Plugin/2.1WrongInterface
4qobject_cast<I7AA7Plugin*> 返回非空WrongInterface
5pluginId / pluginName 非空MetaInfoInvalid
6hostMinimumVersion <= 主程序版本号VersionTooHigh
7x64 Release + Qt 动态 + MinGW 13.1(PE 预检 Machine=0x8664)PlatformMismatch
8pluginInit() 返回 true 且未抛异常InitRaisedException

五、ABI 兼容性红线

  1. I7AA7Plugin 虚函数顺序严禁改动:新纯虚函数只能追加到末尾;
  2. PluginMetaInfo 字段顺序严禁改动:新增字段必须放进 extra(QVariantMap);
  3. 禁止在 SDK 头中定义静态全局对象 / 静态变量;
  4. 不要跨 DLL 边界 new/delete:返回的 QWidget 推荐以 parent 托管;插件自建裸对象须在 pluginUninstall 中自行 delete;
  5. 统一使用 MinGW 动态运行库:不要加 -static-libgcc -static-libstdc++。

六、调试与联调

  • 取得可加载的签名插件后,在「系统 → 插件管理」确认显示「已启用」;
  • 打开「功能分类 → 插件中心」,点击二级菜单查看 UI 挂载;
  • 加载失败点「查看日志」定位报错码;
  • 若崩溃,检查:是否误用私有头文件、是否在 getPluginMetaInfo 中 new QWidget、返回的 QWidget 是否在 pluginUninstall 后仍被持有。