YStudio Y++

DLL / 系统 API(`.yp`)

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

在工程中声明 Windows / DLL 导出函数,供 .yc 用别名调用。结构体仍放 .yt。

运行时通过 LoadLibrary + GetProcAddress 解析导出,不需要导入 .lib。

第三方插件更推荐不用 .yp: 在 .yc 里 加载DLL → 取导出函数 → 调用函数Ex 即可,无需 @模块。见 third-party-dll.md。
本文主要覆盖 系统 API 与「希望用中文别名」的静态声明。

硬约束

  1. .yc 中调用的是声明末尾的中文/别名,不是 DLL 导出名(除非别名相同)。
  2. 调用别名时必须带括号,参数类型与 .yp 声明一致。
  3. 结构体参数类型在 .yt 定义;指针/缓冲边界见 dll-pointers.md;命令签名见 basic-dll.md / basic-pointer.md。
  4. 默认调用约定多为 stdcall;C 库常见 cdecl,写错会崩或栈不平。
  5. 不要虚构未在 .yp 声明的别名。
  6. &类型 / 引用 只用于 .yt 结构指针,不是任意 int*(int* 用 DLL_整数指针32)。
  7. 第三方插件优先 加载DLL→取导出函数→调用函数Ex,不必为每个导出写 .yp(见 third-party-dll.md)。

声明签名模板

[库短名] [返回类型] API导出名(类型 参1, …) 别名 [@"库.dll"] [stdcall|cdecl]
片段示例 含义
整数 MessageBoxW(整数, 文本, 文本, 整数) 消息框 返回整数;宽串用 文本
user32 逻辑 GetWindowRect(整数, &矩形) 取窗口矩形 结构出入参
整数 strlen(文本A s) 取长度 cdecl 窄串 + cdecl
kernel32 逻辑 ReadFile(整数, 字节 缓冲[], 整数, 整数) 读取数据 字节数组形参

新建

工程树 → 源代码 → 右键 → 新建 API 文件(后缀 .yp)。

语法

库名:多种写法(系统 API 可省略库名)

逻辑 GetWindowRect(整数 窗口句柄, &矩形 框) 取窗口矩形   // 系统 API:自动在 user32 等中查找
@"gdi32.dll"                          // 可选:登记库
gdi32 整数 GetDeviceCaps(...) 取设备能力   // 库短名
@模块 g_插件模块                       // 从 global.yc 里 加载DLL 的全局句柄取导出(仅当你坚持用.yp 别名时)
整数 GetTickCount() 取启动毫秒 @"kernel32.dll"  // 别名后写库

同一文件里用 @"user32.dll" 切一次库后,后面的声明可以不加短名前缀(跟当前库)。

声明函数

[库短名] [返回类型] API导出名(类型 参数,...) 别名 [@"库.dll"] [stdcall|cdecl]
部分 含义
库短名 可选;gdi32 等同 gdi32.dll
返回类型 可省略;省略=无返回值
API导出名 DLL 真实导出名
参数 见下表
别名 Y++ 中调用的名字
调用约定 可选;默认 stdcall(winapi 同义);亦可写 cdecl。DLL 导出面板生成的 .yp 会自动带上工程约定
整数 Add(整数 a, 整数 b) 相加 stdcall
整数 strlen(文本A s) 取长度 cdecl

返回类型可省略 = 无

user32 DestroyWindow(整数 窗口句柄) 销毁窗口
无 DestroyWindow(整数 窗口句柄) 销毁窗口   // 显式写「无」也可以

结构体引用(与回调、C 指针的区别)

三种等价写法(仅自定义 .yt 类型,编组为 Win 结构指针,类似 RECT*):

&矩形 框
矩形 &框
引用 矩形 框

结构字段会自动编组:

字段 行为
标量 / 嵌套 .yt(≤4 层) 打成连续 Win POD,出入参回写
定长数组 T 名[N](N≤256) 同上(含嵌套结构内文本缓冲)
文本 可写宽缓冲(≥1024 wchar)→ LPCWSTR,调用后回写
字节集 非空:BYTE* 指向原缓冲(原地改写即生效);空:scratch≥4096,调用后按尾零裁剪回写;DLL 改指针无法接管
不定长 [] / N>256 跳过该字段

完整规则与示例见 dll-pointers.md §3.5。

宽窄串(必读): .yt 的 文本 一律编成 LPCWSTR;对接 LPCSTR 写 文本A(与顶层 .yp 同路径,UTF-8)。旧绕路 整数 + DLL_文本指针A 仍可用。混用易闪退,对照 dll-pointers.md「防闪退:宽窄串」。

数组 / 字节缓冲(传给 DLL 的连续内存)

写法 传给 DLL .yc 侧
字节 缓冲[] BYTE*(空则 nullptr) 字节 缓冲[](对应字节数组缓冲)
字节集 缓冲 BYTE*(同上) 字节集 亦可(勿再写 [])
整数 表[] / 长整数 表[] long long* 同左
短整数 表[] long long*(与 .yc 短整数数组元素一致) 短整数 表[]
小数 表[] / 双浮点 表[] double* 同左
单浮点 表[] float* 单浮点 表[]
逻辑 表[] int* 逻辑 表[]

不支持 []:文本 / 文本A、结构体引用(&类型)、子程序指针。

'.yp — 字节数组形参
kernel32 逻辑 ReadFile(整数 句柄, 字节 缓冲[], 整数 要读, 整数 已读指针) 读取数据

'.yc
字节 缓冲[]
数组调整长度(缓冲, 4096)
整数 已读 = 0
读取数据(h, 缓冲, 数组长度(缓冲), DLL_整数指针32(0))
' 若需读回已读字节数:先 p = DLL_整数指针32(0),调用后再 DLL_读整数指针32(p)

说明: - 请写 类型 名[](与普通变量一致),例如 字节 字节数组[] - 字节 字节数组(无 [])只是单个字节,不是数组 - 整数[] 元素是 64 位;若 DLL 要的是 32 位 int*,请继续用地址缓冲手段

C / Win Y++ .yp
RECT* / POINT* 等结构指针 &矩形 / &坐标点(须先在 .yt 定义)
LPCWSTR / wchar_t* 文本
LPCSTR / char*(窄字符) 文本A
int / INT_PTR / 句柄 整数(或长整数等)
BOOL 逻辑
BYTE* / 字节数组 字节 名[](或 字节集)
int64_t* / 元素数组 整数 名[] 等
函数指针回调 子程序指针 名(不要加 &)

说明:当前 & / 引用 不是任意 int*,而是「指向 .yt 结构体」的出入参。

裸指针请用支持库 DLL支持 命令转成地址,再交给 .yp 里声明为 整数 的形参:

命令 用途
DLL_文本指针W(文本) → LPCWSTR 地址
DLL_文本指针A(文本) → UTF-8 LPCSTR 地址(TLS 缓冲)
DLL_整数指针32([初值]) → WinAPI int*(TLS);读回用 DLL_读整数指针32
DLL_整数指针(整数变量) → Y++ 64 位整数变量地址(非标准 int*)

完整对照(含字节集指针、const、结构嵌套、库名省略、按地址 Call): 见 dll-pointers.md。
第三方插件(加载路径、出参、long*、回调、类封装): 见 third-party-dll.md。

//.yp
kernel32 整数 lstrlenW(整数 串指针) 宽串长度指针
kernel32 逻辑 GetExitCodeProcess(整数 进程, 整数 退出码指针) 取进程退出码指针

//.yc
整数 n = 宽串长度指针(DLL_文本指针W("hello"))
长整数 p = DLL_整数指针32(0)
取进程退出码指针(取当前进程(), p)
整数 code = DLL_读整数指针32(p)

Y++ 没有 string 关键字,字符串用 文本(宽字符)或 文本A(窄字符)。

子程序指针(回调)不要加 &:

逻辑 EnumWindows(子程序指针 回调, 整数 参数) 枚举窗口

与支持库命令同名时,工程 .yp 别名优先。

.yc 调用

矩形 r
如果 (取窗口矩形(主窗口.句柄, r))
    消息框(0, "宽=" + 到文本(r.right - r.left), "标题", 0)

从 C 声明一键转换

打开 .yp 后:工程树或编辑器右键 → API 转 Y++ 声明…