YStudio Y++

静态模块工程(.ys)

Y++ / YStudio 开发文档 · 一点滴

模块工程用 Y++ 编写可复用函数,编译产物为加密的 .ys 静态模块包,可被窗口工程或 DLL 工程静态链接调用。

相关:dll-project.md · 工程结构.md

与 DLL 的区别

DLL 工程 模块工程
产物 .dll(+ 导入 .lib) 加密 .ys(内含静态库 + 公开元数据)
链接方式 运行时 加载DLL 编译期静态链接进宿主
导出语法 导出 / .yex 相同
查看实现 可用源码工程 禁止:信息对话框只显示公开命令

硬约束

  1. .ysproj 中 "type": "module"。
  2. 先写 函数,再在 exports.yex 用 导出 登记;未导出的函数不会进入 .ys 公开表。
  3. 新建时选 x64 或 x86;宿主工程位数须与模块一致(.ys 清单里带 arch,链接前会校验)。
  4. 不需要像 DLL 那样选 stdcall/cdecl:模块是静态库,调用约定由编译器按架构生成;stdcall/cdecl 只影响 DLL 的 PE 导出。
  5. .ys 不能当源码打开;双击或「查看模块信息」只看公开 API。资源管理器图标走设置里的「关联文件类型」(.ys 独立紫色 YS 图标)。
  6. 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,不会弹窗。

调试请走宿主窗口工程:

  1. 模块工程 F5 编译出 .ys
  2. 新建或打开同架构的窗口工程 → 项目树「引用模块」→ 添加该 .ys
  3. 在窗口事件里直接调用导出函数(如 相加(1, 2))
  4. 在窗口工程里 F5 运行,或 Shift+F5 调试(可对模块 .yc 下断点)

改模块后需重新 F5 编译模块,再编译/调试宿主。

新建

欢迎页 → 创建项目 → 模块项目(.ys 静态库)。