模块工程用 Y++ 编写可复用函数,编译产物为加密的 .ys 静态模块包,可被窗口工程或 DLL 工程静态链接调用。
相关:dll-project.md · 工程结构.md
与 DLL 的区别
| DLL 工程 | 模块工程 | |
|---|---|---|
| 产物 | .dll(+ 导入 .lib) |
加密 .ys(内含静态库 + 公开元数据) |
| 链接方式 | 运行时 加载DLL |
编译期静态链接进宿主 |
| 导出语法 | 导出 / .yex |
相同 |
| 查看实现 | 可用源码工程 | 禁止:信息对话框只显示公开命令 |
硬约束
.ysproj中"type": "module"。- 先写
函数,再在exports.yex用导出登记;未导出的函数不会进入.ys公开表。 - 新建时选 x64 或 x86;宿主工程位数须与模块一致(
.ys清单里带arch,链接前会校验)。 - 不需要像 DLL 那样选 stdcall/cdecl:模块是静态库,调用约定由编译器按架构生成;stdcall/cdecl 只影响 DLL 的 PE 导出。
.ys不能当源码打开;双击或「查看模块信息」只看公开 API。资源管理器图标走设置里的「关联文件类型」(.ys独立紫色 YS 图标)。- YSS:模块工程与 DLL 相同,源码中使用
加载YSS/应用YSS(或放入有效.yss)须先开通 YSS 样式;未开通不能编译/打包.ys。打包后清单带usesYss;未开通的宿主不能添加引用、不能导入调用、不能链接含 YSS 的.ys。
写模块与备注
函数上方备注会出现在宿主「查看模块信息」与命令提示风格说明中:
/// @说明 两数相加,返回和
/// @参数 a│第一个加数
/// @参数 b│第二个加数
/// @示例 相加(1, 2)
函数 相加(整数 a, 整数 b) 整数 {
返回(a + b)
}
exports.yex:
导出 "相加"
快捷键:Ctrl+E(在 .yex 中)一键补全尚未导出的函数。
宿主引用
窗口 / DLL 工程左侧项目树 → 引用模块:
| 菜单 | 作用 |
|---|---|
| 添加模块… | 将 .ys 复制到工程 模块/,相对路径写入 moduleDependencies 并落盘 |
| 删除模块 | 从工程引用中移除(不删磁盘文件) |
| 查看模块信息 | 公开命令 / 参数 / 说明 / 示例(无源码) |
打开工程时若引用路径失效,会提示 重新添加 / 移除引用 / 取消(取消则保留引用,下次仍提示)。
编译宿主时 IDE 会解开 .ys 中的静态库并链接;源码侧可直接调用导出的函数名(如 相加(1,2)),补全/悬停/参数提示与支持库命令一致。
安全说明
.ys为加密容器(完整性校验),不含.yc源码。- 信息对话框只解密公开元数据,不展示实现。
- 逆向只能得到目标代码级符号,无法还原原始 Y++ 源;发行混淆构建可进一步加固 IDE 侧密钥材料。
运行与调试
模块没有独立进程:工具栏配置固定为 Release(无 Debug);F5 / 编译只生成 发布/<arch>/Release/<名>.ys,不会弹窗。
调试请走宿主窗口工程:
- 模块工程 F5 编译出
.ys - 新建或打开同架构的窗口工程 → 项目树「引用模块」→ 添加该
.ys - 在窗口事件里直接调用导出函数(如
相加(1, 2)) - 在窗口工程里 F5 运行,或 Shift+F5 调试(可对模块
.yc下断点)
改模块后需重新 F5 编译模块,再编译/调试宿主。
新建
欢迎页 → 创建项目 → 模块项目(.ys 静态库)。