在工程中声明 Windows / DLL 导出函数,供 .yc 用别名调用。结构体仍放 .yt。
运行时通过 LoadLibrary + GetProcAddress 解析导出,不需要导入 .lib。
第三方插件更推荐不用
.yp: 在.yc里加载DLL→取导出函数→调用函数Ex即可,无需@模块。见 third-party-dll.md。
本文主要覆盖 系统 API 与「希望用中文别名」的静态声明。
硬约束
.yc中调用的是声明末尾的中文/别名,不是 DLL 导出名(除非别名相同)。- 调用别名时必须带括号,参数类型与
.yp声明一致。 - 结构体参数类型在
.yt定义;指针/缓冲边界见 dll-pointers.md;命令签名见 basic-dll.md / basic-pointer.md。 - 默认调用约定多为
stdcall;C 库常见cdecl,写错会崩或栈不平。 - 不要虚构未在
.yp声明的别名。 &类型/引用只用于.yt结构指针,不是任意int*(int*用DLL_整数指针32)。- 第三方插件优先
加载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++ 声明…