已开启
[Bug]: [ffi.c] 依赖 dll 的"双命名"查找不一致,且不复制到输出目录:构建成功 ≠ 能运行 #703
chh_itt创建于  6 天前
chh_itt
chh_itt
6 天前 创建

感谢对仓颉社区的支持与关注,欢迎反馈缺陷。 | Thanks for your support and attention to the community. We welcome feedback on any issues.

领域 | Domain

Tools

发生了什么问题? | Describe the issue that occurred.

Windows 上通过 foreign + [ffi.c] 使用 C 动态库时,构建期与运行期的
dll 查找行为不一致,且失败模式完全静默:

  1. 构建期:cjpm 按包名查找 libs/libdanqing.dll(lib 前缀)——没有它
    构建直接失败("can not find the library 'danqing'");
  2. 运行期:Windows 加载器按 import 表记录的裸名查找 danqing.dll
    (无前缀)——即便构建成功,若该文件不在 exe 旁边,进程以
    0xC0000135 (STATUS_DLL_NOT_FOUND) 退出;
  3. cjpm 不会自动把依赖 dll 复制到 target\release\bin\——开发者必须
    手工把两份文件(danqing.dll 与 libdanqing.dll)都放到输出目录。

实际排查经历:最初现象是"运行时负退出码、无任何错误信息",需要用
dumpbin /dependents 查 import 表才能定位到缺失 dll,对新人非常不友好。

期望行为是什么? | What is the expected behavior?

  1. cjpm build 后自动将 [ffi.c] 依赖的 dll 复制到输出目录(可参照
    Cargo 的构建脚本链接模式);
  2. 或 cjpm run 时做一层依赖 dll 存在性检查,给出可读诊断而非静默的
    加载器失败;
  3. 文档明确"构建期 lib 前缀命名 vs 运行期裸名"的差异。

如何复现该缺陷? | How to reproduce the bug?

  1. 任意含 foreign 调用 + [ffi.c] 声明动态库依赖的工程;
  2. 确保 libs/lib<name>.dll 存在 → cjpm build 成功;
  3. 把 <name>.dll 从 target\release\bin\ 移走 → 运行 exe:
    进程以 0xC0000135 退出,无任何提示。

更完整的实践记录(含两条路径的解决方案对比):
https://gitcode.com/m0_74475107/Danqing(CHANGELOG 与 docs/)

其他补充信息 | Additional information

附带一个同属 cjpm 的文档问题:[package].organization 字段一旦填写,
会要求源码 package 声明同步改为 <org>::<name>(构建报错
"the package name in ... is wrong, the right name should be 'org::name'"),
文档未前置说明该语义,建议一并澄清。

cjc版本信息 | cjc version information

Cangjie Compiler: 1.1.3 (cjnative)
Target: x86_64-w64-mingw32

分支版本信息 | Branch version information

likedislike
chh_ittchh_itt
6 天前 添加了label:bug
xuanjzxuanjz管理员
4 天前 关联了看板:105