d:更好C中用d类
原文
如何在D中带betterC
使用带有C++链接
的类
.
在D
中,可在-betterC
条件下用类.是的,可以!
D
中-betterC
不能用类
的问题是:依赖
运行时勾挂
和来自D运行时库
的类型信息
.
而betterC
禁止使用运行时类型信息
,所以betterC
不能用依赖它的设施
.但由于不依赖
任何运行时库,betterC
不限制C和C++
的链接.
难点在哪?
实例化extern(C++)
类时,有难点,当前最新版编译器,在无以下两点时难取得类
的初始内存块
.
1:依赖TypeInfo
,用typeid(ClassFoo).initializer
.
2,创建挂名类的挂名域
实例,并复制内存到新分配的缓冲区
.
两个选项都有缺点,1
在betterC
时,只有手动创建和删除
一些符号时
才行.2
也有限制,因为用户不能用普通类析构器
.如果不用特殊析构器
,可如下轻松取类初化器
.
static auto initializer()
{
alias T = typeof(this);
void[__traits(classInstanceSize, T)] t = void;
scope T s = new T;
t[] = (cast(void*)s)[0 .. t.length];
return t;
}
也可自定义
析构器来绕过它.但这样就不能raii
了.
合理方法
LDC
有个取类类型的初化器
的__traits(initSymbol)
特征,将在规范
中描述,且dmd
也已实现,只需要创建自定义分配和消灭
函数模板.
T alloc(T, Args...)(auto ref Args args)
{
enum tsize = __traits(classInstanceSize, T);
T t = () @trusted {
import core.memory : pureMalloc;
auto _t = cast(T)pureMalloc(tsize);
if (!_t) return null;
import core.stdc.string : memcpy;
memcpy(cast(void*)_t, __traits(initSymbol, T).ptr, tsize);
return _t;
} ();
if(!t) return null;t.__ctor(args);
return t;
}
void destroy(T)(ref T t)
{
static if (__traits(hasMember, T, "__dtor"))
t.__dtor();
() @trusted {
import core.memory : pureFree;
pureFree(cast(void*)t);
}();
t = null;
}
用此两个函数,可如下在betterC
中分配新类实例
:
extern(C++) class Foo
{
this(int a, float b)
{
this.a = a * 2;
this.b = b;
}
int a;
float b;
bool c = true;
}
extern(C) int main()
{
Foo foo = alloc!Foo(2, 2.0f);
scope(exit) destroy(foo);
int a = foo.a; // 4
float b = foo.b; // 2.0
bool c = foo.c; // true
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现