d从创建新对象的接口调用函数时垃集错误

原文

//示例代码:
interface IFont
{
  IFont createFontWithSize(int size);
}
//主代码

import common;
class TTFFont : IFont
{
  IFont createFontWithSize(int size){return new TTFFont;}
}

export extern(System) IFont newFont()
{
  auto ret = new TTFFont();
  GC.addRoot(ret);
  return ret;
}
//DLL代码:

import common;

Runtime.initialize();
IFont function() newFont;
newFont = loadSymbol("newFont");
IFont myFont = newFont();
IFont otherFont = myFont.createFontWithSize(32);
//一段时间后`垃集`

因为过了一段时间,还未收集它,我实际上需要把GC.addRoot放在createFontWithSize函数中.从而使它无法使用.
D的DLL都在独立于主进程GC上下文中运行,因此如果不再维护对DLL新建对象引用,则可收集它.可以把它们链接在一起,这样就可共享相同的GC,如下所示:

// mydll.d
extern(C) {
    void gc_setProxy(void* p);
    void gc_clrProxy();
}
export void MyDLL_Initialize(void* gc) {
    gc_setProxy(gc);
}
export void MyDLL_Terminate() {
    gc_clrProxy();
}


// main.d
extern (C) {
    void* gc_getProxy();
}
void main() {
    MyDLL_Initialize(gc_getProxy()); 
//用DLL共享本进程的GC
    scope(exit) MyDLL_Terminate();
    /*干活...*/
}

这只适用于dmd窗口(使用ldc,对所有混合的,可得到共享的druntime),不必自己设置代理,Runtime.loadLibrary会为你做.
一定要确保使用的是Runtime.loadLibrary!我不认为不能单独使用SimpleDllMain,所以这可能是奇怪的问题.
这是另一个必须记住令人困惑的差异.维基有已知编译器差异最新列表吗?

posted @   zjh6  阅读(46)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示