В D мой сборщик мусора каждый раз запускает мое приложение.Сбой коллектора мусора при использовании функций WinAPI
модуль для Windows:
pragma(lib, "user32.lib");
import std.string;
extern(Windows) {
void* CreateWindowExW(uint extendedStyle ,
const char* classname,
const char* title,
uint style,
int x, int y,
int width, int height,
void* parentHandle,
void* menuHandle,
void* moduleInstance,
void* lParam);
}
class Window {
private void* handle;
private string title;
this(string title, const int x, const int y, const int width, const int height) {
this.title = title;
handle = CreateWindowExW(0, null, toStringz(this.title), 0, x, y, width, height, null, null, null, null);
if(handle == null)
throw new Exception("Error while creating Window (WinAPI)");
}
}
Главный модуль:
import std.stdio;
version(Windows) {
import windows;
extern (Windows) {
int WinMain(void* hInstance, void* hPrevInstance, char* lpCmdLine, int nCmdShow) {
import core.runtime;
Runtime.initialize();
scope(exit) Runtime.terminate();
auto window = new Window("Hello", 0, 0, 0, 0);
writeln("test");
return 0;
}
}
}
Это дает мне нарушение прав доступа в месте 0. Когда я просматривать dissassembly, это сбой в
0040986F mov ecx,dword ptr [eax]
Эта сборка находится внутри _gc_malloc
.
EDIT: Вот новый код:
Windows, модуль:
pragma(lib, "user32.lib");
import std.utf;
extern(Windows) {
void* CreateWindowExW(uint extendedStyle ,
const wchar* classname,
const wchar* title,
uint style,
int x, int y,
int width, int height,
void* parentHandle,
void* menuHandle,
void* moduleInstance,
void* lParam);
}
class Window {
private void* handle;
private wstring title;
this(wstring title, const int x, const int y, const int width, const int height) {
this.title = title;
handle = CreateWindowExW(0, null, toUTFz!(wchar*)(this.title), 0, x, y, width, height, null, null, null, null);
if(handle == null)
throw new Exception("Error while creating Window (WinAPI)");
}
}
WinMain:
int WinMain(void* hInstance, void* hPrevInstance, char* lpCmdLine, int nCmdShow) {
import core.runtime;
try {
Runtime.initialize();
scope(exit) Runtime.terminate();
auto window = new Window("Hello", 0, 0, 0, 0);
writeln("test");
} catch(Exception ex) {
writeln(ex.toString);
}
return 0;
}
Когда я запускаю этот второй код, я также получаю Нарушение доступа, по случайному (мне) адресу.
Dissasembly (внутри __d_createTrace
):
0040C665 cmp dword ptr [ecx+1Ch],0
Runtime.initialize и выход из области выполнения runtime.terminate должны быть как снаружи, так и снаружи, попробовать, поместить их в самый верх функции, а затем попробовать свой код. То, что происходит сейчас, - это новое окно, генерирующее исключение (например, Дэвид сказал, вам нужно сначала зарегистрировать класс окна, а не передать null), а затем в конце попытки завершается. Таким образом, внутри catch, материал не настроен, и вызов toString не может выполнять свою работу. Поэтому переместите эти две строки Runtime выше, и вы должны получить сообщение с хорошим сообщением об исключении. –