相同的代码在共享库中不会(有点)工作,但在程序中直接使用时可以工作

Same code won't work (kind of) in a shared library, but works when used directly in the program

我创建了一种脚本语言,当它完美运行时,我将所有代码放在一个共享库中,并为其制作了一个包装器,但相同的代码在共享库中无法运行。我注意到代码在共享库中运行得更快,但它总是崩溃,由于内存问题,说索引超出数组长度,但完全相同的代码在库外运行完美。
我还注意到,如果我减少它必须做的工作量,它会在崩溃前持续更长时间。

我的问题是导致此崩溃的原因是什么,我该如何阻止它发生?

P.S:我没有把所有的代码都包括进去,因为整个代码有1039行(但是如果你需要解决问题的代码,我可以link) ,但我已将崩溃跟踪到一个函数。令人困惑的是,那个函数总是在第 821 次被调用时崩溃,以前从来没有,那是为了更优化的代码,当代码没有优化,使用更多 CPU 时,它会在 702 时崩溃。

另外:我正在使用 DMD2,函数是使用 extern(C) 导出的,我正在 Linux 系统 Ubuntu 14.04 上测试所有这些。这就是我编译库的方式:

dmd -debug -gc "qscript.d" "qcompiler.d" "lists.d" "dllmain.d"  "-shared"  "-odobj/Debug" "-of/home/nafees/Desktop/Projects/QScr/QScr/bin/Debug/libQScr.so" -w -vcolumns

并使用 dlopen 函数加载。

再一次,如果你错过了我的问题:是什么导致了这次崩溃,我该如何阻止它发生?编辑:以及如何禁用垃圾收集器,gc.disable 不起作用,gc 未定义。

编辑:我已经跟踪 'why' 崩溃正在发生,我在所有文件中放置了调试代码,只是为了发现垃圾收集器正在扰乱加载到内存中的脚本文件.我'fixed'的问题,居然没有,加了个检查。它检查脚本是否不是 'alright',然后将其重新加载到内存中。这是避免了崩溃,但问题仍然存在。这会将问题更改为:
我怎样才能禁用垃圾收集器 > 顺便说一句,我试过了 gc.disable,但是 DMD 说 gc 是未定义的。

我自己解决了这个问题。正如我在问题的编辑中所说:我将问题跟踪到垃圾收集器,垃圾收集器弄乱了加载到内存中的脚本文件,导致库崩溃,因为垃圾收集器已从中删除了脚本的内容记忆。为了解决这个问题,我添加了:

import core.memory;
...
GC.disable();

这解决了整个问题。

您必须在第一次加载共享库时初始化运行时。为此,您需要将类似的内容添加到您的库中:

private __gshared bool _init = false;
import core.runtime: rt_init, rt_term;

export extern(C) void init()
{
    if (!_init) rt_init;
}

export extern(C) void terminate()
{
    if (_init) rt_term;
    _init = false;
}

我的意思是像那样,而不是完全那样。由于我们不知道您的脚本引擎是如何使用的,因此初始化计数器也可能有效:

private __gshared uint _init;
import core.runtime: rt_init, rt_term;

export extern(C) void init()
{
    if (!_init) rt_init;
    ++init;
}

export extern(C) void terminate()
{
    --init;
    if (!_init) rt_term;
}

无论如何你应该明白了。 GC 未定义,因为您没有初始化低级 D 运行时。