On Sunday, 5 May 2013 at 09:52:53 UTC, Namespace wrote:
Here a test example:
http://dpaste.1azy.net/2cfc8ead

The memory is allocated through the SDL as you can see.

1) You don't need to call unload on any Derelict loaders. That is handled automatically by Derelict using static module destructors just as you have here. And that leads to

2) Module destructors are run before the gc runs its final collection at shutdown. So if in a destructor you try to call into one of the libraries Derelict binds, you will be calling into a library that is already unloaded, hence the error.

Never rely on destructors to release memory. Aside from this Derelict-specific issue, you have no control over when, if, or in what order the destructors are called. This can lead to all sorts of subtle bugs.

The IMO ideal way to handle this is to give your app a terminate() function somewhere that is always called before the app exits and which initiates a clean release of system resources. Assuming a game:

****
void main() {
    initialize();
    run();
    scope(exit) terminate();
}

void terminate() {
    Game.terminate();
    Audio.terminate();
    Network.terminate();
    Graphics.terminate();
    ...
}
****

I adopted this style long ago in C and it applies well to D. I never rely on destructors except for logging, statistics, or other non-critical things. I release all C-side memory through a terminate chain.

Reply via email to