On 2011-07-14 01:17, David Nadlinger wrote:
Currently, no memory can be allocated at all during garbage collection runs, which is where destructors are usually called.David
That explains it. Do you know when this feature will be available, if at all? Here is another interesting case, where I am using external libraries (FMOD) in this case. I have two different cases here, but they have two notable things in common. Both use WinMain as entry point and they both originate in the class Foo. In the first case, I use the class Foo, which has the "Sound" class as a private member. If foo omits the call to allocate the sound class no "Memory Allocation Failure" occurs. This error is also avoided if the two lines in the static destructor of sound is omitted: FMOD_System_Close(m_system); FMOD_System_Release(m_system); How come these external functions generates a Memory Allocation Failure when they use malloc for their memory allocation? Also worth noticing is that in the non-static destructor FMOD_Sound_Release is called without any problems, if the two function calls are omitted. One other thing; how come no "Memory Allocation Failure" occurs, when I do not allocate the sound class, since the static de-/constructors of the class are still called? In the second case, the exact same functions are called except that everything takes place in-lined in the Foo constructor. Case 1: Memory Allocation Failure and Sound destructor is not called. Case 2: Everything works as expected.
// Import WINAPI import win32.windows; // Core API import core.runtime; import std.range; import std.string; // FMOD import fmod.fmod; extern (Windows) int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { int result; void exceptionHandler(Throwable e) { throw e; } try { Runtime.initialize(&exceptionHandler); result = myWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow); Runtime.terminate(&exceptionHandler); } catch (Error o) { MessageBoxA(null, cast(char *) o.toString(), "Error", MB_OK | MB_ICONEXCLAMATION); result = 0;// failed } return result; } int myWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { Foo foo = new Foo; return (foo !is null); } class Foo { public: this() { //m_sound = new Sound(r"C:\acdc.ogg"); } ~this() { MessageBoxA(null, "Never Called", "Error", MB_OK | MB_ICONEXCLAMATION); } private: Sound m_sound; } class Sound { public: static this() { if(FMOD_System_Create(&m_system) != FMOD_RESULT.FMOD_OK) throw new Error("Failed to create fmod system."); if(FMOD_System_Init(m_system, 2, FMOD_INIT_NORMAL, null) != FMOD_RESULT.FMOD_OK) throw new Error("Failed to initialize fmod."); } static ~this() { // Close and release system (omitting these prevents any errors from occuring) FMOD_System_Close(m_system); FMOD_System_Release(m_system); } this(string file) { if(FMOD_System_CreateSound(m_system, cast(char *) file.toStringz, FMOD_HARDWARE | FMOD_LOOP_OFF, null, &m_sound) != FMOD_RESULT.FMOD_OK) throw new Error("Failed to create sound."); } ~this() { // Release Sound FMOD_Sound_Release(m_sound); } private: static FMOD_SYSTEM * m_system; FMOD_SOUND * m_sound; }
// Import WINAPI import win32.windows; // Core API import core.runtime; import std.range; import std.string; // FMOD import fmod.fmod; extern (Windows) int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { int result; void exceptionHandler(Throwable e) { throw e; } try { Runtime.initialize(&exceptionHandler); result = myWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow); Runtime.terminate(&exceptionHandler); } catch (Error o) { MessageBoxA(null, cast(char *) o.toString(), "Error", MB_OK | MB_ICONEXCLAMATION); result = 0;// failed } return result; } int myWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { Foo foo = new Foo; return (foo !is null); } class Foo { public: this() { FMOD_SYSTEM * m_system; FMOD_SOUND * m_sound; if(FMOD_System_Create(&m_system) != FMOD_RESULT.FMOD_OK) throw new Error("Failed to create fmod system."); if(FMOD_System_Init(m_system, 2, FMOD_INIT_NORMAL, null) != FMOD_RESULT.FMOD_OK) throw new Error("Failed to initialize fmod."); if(FMOD_System_CreateSound(m_system, cast(char *) r"C:\acdc.ogg", FMOD_HARDWARE | FMOD_LOOP_OFF, null, &m_sound) != FMOD_RESULT.FMOD_OK) throw new Error("Failed to create sound."); // Release Sound FMOD_Sound_Release(m_sound); // Close and release system FMOD_System_Close(m_system); FMOD_System_Release(m_system); } ~this() { MessageBoxA(null, "Called", "Error", MB_OK | MB_ICONEXCLAMATION); } }