d链接到有类静态库时缺少模块信息
原文
我遇见了一些问题,在运行时类型信息
中,应该包含的moduleinfo
和classinfo
丢失了,但只在通过静态库
链接时才丢失.示例:
libci.d:
module libci;
class C
{
}
extern(C) void foo()
{
import std.stdio;
auto c = new C;
writeln("C的类信息", typeid(c));
auto x = ClassInfo.find("libci.C");
writeln("搜索:", x);
}
version(works) static this()
{
import std.stdio;
writeln("这里");
}
testit.d:
import std.stdio;
import libci;
void main()
{
foo();
auto ci = ClassInfo.find("libci.C");
writeln("主中: ", ci);
foreach(m; ModuleInfo)
{
writeln(m.name);
}
}
用
dmd testit.d libci.d
//编译与用如下编译
dmd -lib libci.d
dmd -L-L. -L-lci testit.d
不一样,后者缺少libci
!
因此,尽管如果
直接使用它,classinfo
是可用的,也未链接libci
的ModuleInfo
.exe
中错误的删除了ModuleInfo
.
在构建库时,如果启用version=works
,则会包含ModuleInfo
.
不确定这是druntime
还是dmd
错误,标记为dmd
.
注意,该行为非常古老,在Linux
和OSX
上都有.早在2.064
就已测试过了
它与静态库
中去掉不用类/模块
矛盾.
如果真想从静态库
中拖入所有类
,一种方法是从公共模块
中引用所有类
.
拥有所有类
的显式列表与Object.factory
的目的矛盾,都难实现.
另一种方法是为每个
模块生成目标
文件,并显式链接
它们(链接器
不会丢弃目标文件).
Dub
以--build-mode=singleFileIIRC
形式来支持.
再或者是使用共享库
或告诉链接器
包括整个归档
文件,对ld
,合理地命名为--whole-archive/--no-whole-archive
.
可惜,dmd
当前重排
了链接器标志(15574#问题
),所以下面方法不管用.
-L--whole-archive mystaticlib.a -L--no-whole-archive
相反,必须调用cc
来自己链接.
这是因小失大
.先要解决兆字节
大小的模板符号名
.然后,需要完整支持共享库
.moduleinfo
增加的几千字节不重要.删除未用的classinfo
?然后,需要删除Object.factory
方法.
我从模块
中引用了类信息
,并调用了该函数
.为什么链接器
排除了它?这是个真实的漏洞
.
不能有Object.factory
,然后修剪掉
所有不直接使用的classinfo
.但是在该示例
中,我直接用它,它仍然被修剪掉
.
不管是否需要
它,它都是当前运行时
的特性.不再关心现有代码
了吗?
我完全赞成过时Object.factory
,也赞成你更新到std.encoding
.但可能有代码期望Object.factory
工作,不然,它不会工作.
注意,在我给的示例中,包含模块信息
未增加二进制文件的大小.ClassInfo
已在二进制文件中,因此会加入
类可能使用的所有其他内容
.
不仅如此,用-lib
开关构建,也不行,但不用它,则可以.不一致
对D来说是不好的,不管Object.factory
特性的实用性
如何.
一些UI
解析器*依赖*
类列表和工厂.来避免易错的手动
注册UI
类.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现