Windows 创建窗口时,ntdll.dll中的SIGSEGV

Windows 创建窗口时,ntdll.dll中的SIGSEGV,windows,winapi,rust,Windows,Winapi,Rust,我正在尝试创建一个简单的GUI应用程序,在Windows7x64上显示一个窗口。我使用FFI是为了从rust调用Windows API,但我一直在ntdll.dll中获取SIGSEGV。我做错什么了吗 整个代码可以在上找到,但我会在这里发布主要内容 winapi.h和winapi.c是Windows API的c包装器。它们被编译到一个静态库(libwinapi) winapi.rs是链接到FFI的libwinapi的板条箱 main.rs链接到winapi并显示一个窗口 rustc-v的信息

我正在尝试创建一个简单的GUI应用程序,在Windows7x64上显示一个窗口。我使用FFI是为了从rust调用Windows API,但我一直在ntdll.dll中获取SIGSEGV。我做错什么了吗

整个代码可以在上找到,但我会在这里发布主要内容

  • winapi.h和winapi.c是Windows API的c包装器。它们被编译到一个静态库(libwinapi)
  • winapi.rs是链接到FFI的libwinapi的板条箱
  • main.rs链接到winapi并显示一个窗口
rustc-v
的信息如下:

C:\Program Files (x86)\Rust\bin\rustc.exe 0.11-pre-nightly (7d725a3 2014-04-21 23:01:39 -0700)
host: i686-pc-mingw32
winapi.h winapi.rs 构建日志 输出日志
PS C:\Users\masato\Documents\GitHub\rust\u sample>gdb。\main.exe
GNU gdb(gdb)7.6
版权所有(C)2013免费软件基金会。
许可证GPLv3+:GNU GPL版本3或更高版本
这是自由软件:您可以自由更改和重新发布它。
在法律允许的范围内,不存在任何担保。键入“显示复制”
和“显示保修”了解详细信息。
此GDB配置为“i686-w64-mingw32”。
有关错误报告说明,请参阅:
...
从C:\Users\masato\Documents\GitHub\rust\u sample\main.exe读取符号…完成。
(gdb)r
启动程序:C:\Users\masato\Documents\GitHub\rust\u sample\main.exe
[新线程7060.0x1a0c]
[新螺纹7060.0x422c]
句柄:0x400000
程序接收信号SIGSEGV,分段故障。
ntdll中的0x76f3fc62!ZwMapViewOfSection()来自C:\Windows\system32\ntdll.dll
(gdb)英国电信
#ntdll中的0 0x76f3fc62!ZwMapViewOfSection()来自C:\Windows\system32\ntdll.dll
#ntdll中有1 0x76f3fc62!ZwMapViewOfSection()来自C:\Windows\system32\ntdll.dll
#来自C:\Windows\syswow64\KernelBase.dll的MapViewOfFile()中的2 0x762ceba2
#UxTheme中的3 0x70a25313!从C:\Windows\SysWOW64\uxtheme.dll获取EBITmap()
#UxTheme中的4 0x70a251e5!从C:\Windows\SysWOW64\uxtheme.dll获取EBITmap()
#UxTheme中的5 0x70a253e5!从C:\Windows\SysWOW64\uxtheme.dll获取EBITmap()
#UxTheme中的6 0x70a25a77!从C:\Windows\SysWOW64\uxtheme.dll获取EBITmap()
#UxTheme中的7 0x70a25cc4!从C:\Windows\SysWOW64\uxtheme.dll获取EBITmap()
#UxTheme中的8 0x70a22094!来自C:\Windows\SysWOW64\uxtheme.dll的CloseTheme数据()
#UxTheme中的9 0x70a24260!IsThemePartDefined()来自C:\Windows\SysWOW64\uxtheme.dll
#UxTheme中的10 0x70a2421d!IsThemePartDefined()来自C:\Windows\SysWOW64\uxtheme.dll
#11 0x70a246ed在UxTheme中!C:\Windows\SysWOW64\uxtheme.dll中的MEINITAPIhook()
#从C:\Windows\syswow64\user32.dll中注销ClassW()中的12 0x74daacd4
#从C:\Windows\syswow64\user32.dll中注销ClassW()中的13 0x74daab0e
#ntdll中的14 0x76f3010a!C:\Windows\system32\ntdll.dll中的KiUserCallbackDispatcher()
#15 0x0028fa9c英寸??()
#USER32中的16 0x74dbc6f1!从C:\Windows\syswow64\user32.dll调整WindowRect()
#17 0x004cc196英寸createWindow@8(上下文=0x28fcc8,标题=0x9f3618 L“示例窗口”)
位于C:\Users\masato\Documents\GitHub\rust\u sample\winapi\winapi.C:85
#创建窗口中的18 0x00403bfd::closure.1804()
#操作系统中的19 0x00403b8a::win32::as_utf16_p::h611005080090069878::v0.1()
#创建窗口中的20 0x00403a2e::H0D38B384B04F5AAEBA::v0.1()
#21 0x0040174c主电源::h8f0d1dbc5859ab98gaa::v0.0()
#22 0x0042cac8在起始端::closure.7798()
#rt::task::task::run::Close.40266()中的23 0x004c035c
#rt::unwind::Unwinder::try::try\u fn::hf6246262045efccdJS9::v0.11.pre()中的24 0x004c46b5
#25 0x004cc006锈蚀试验()
#rt::task::task::run::h08ef5174e2ea21abwj8::v0.11.pre()中的26 0x004c0234
#27 0x0042c97d处于启动状态::h07163dfeb7ec96475Ld::v0.11.pre()
#28 0x0042c829语言启动::H59C5DDAEF2AD2AB17PLD::v0.11.pre()
#主管道中的29 0x00401810()
(gdb)

我发现您的代码存在以下问题:

  • 在检查
    CreateWindow
    是否成功之前,请调用
    SetWindowLongPtr
  • 对于
    x
    y
    坐标,应将
    windowRect.left
    windowRect.top
    传递到
    CreateWindow
  • 您的消息循环有点奇怪。经典的
    GetMessage
    循环有什么问题
  • 发送
    WM_PAINT
    消息的代码错误。你不能那样做。如果要重新绘制,请使用
    invalidate
我怀疑上述任何一项都不能解释你的错误。但是,我当然想整理一下消息循环。应该是这样的:

MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}

如果我用我的C编译器编译你的Win32 C代码,那么它运行得很好。这让我认为问题在于你使用的链接过程。
AdjustWindowRect
中的访问冲突似乎很奇怪。堆栈跟踪有一组来自主题API的函数。您的程序是如何实现的?

我对清单没有任何想法。由于错误与视觉样式有关,我将对清单进行试验,看看我能做些什么(可能参考此)。
#include "winapi.h"

bool API_CALL_CONVENTION createWindow(WindowContext* context, LPCTSTR title) {
    WNDCLASS wnd;
    memset(&wnd, 0, sizeof(wnd));
    HINSTANCE hInstance = GetModuleHandle(NULL);
    wnd.lpfnWndProc   = (WNDPROC)DefWindowProc;
    wnd.style         = CS_OWNDC;
    wnd.hInstance     = hInstance; 
    wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wnd.hCursor = LoadCursor(NULL, IDC_ARROW);
    wnd.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); 
    wnd.lpszMenuName = NULL;
    wnd.lpszClassName = TEXT("opengles2.0");

    if (!RegisterClass (&wnd) ) {
        return false; 
    }

    DWORD wStyle = WS_VISIBLE | WS_POPUP | WS_BORDER | WS_SYSMENU | WS_CAPTION | WS_SIZEBOX;

    // Adjust the window rectangle so that the client area has
    // the correct number of pixels
    RECT windowRect;
    windowRect.left = 0;
    windowRect.top = 0;
    windowRect.right = context->width;
    windowRect.bottom = context->height;

    BOOL result = AdjustWindowRect(&windowRect, wStyle, FALSE);
    if (!result) {
        return false;
    }

    HWND handle = CreateWindow(
                        TEXT("opengles2.0"),
                        title,
                        wStyle,
                        0,
                        0,
                        windowRect.right - windowRect.left,
                        windowRect.bottom - windowRect.top,
                        NULL,
                        NULL,
                        hInstance,
                        NULL);

    // Set the ESContext* to the GWL_USERDATA so that it is available to the 
    // ESWindowProc
    SetWindowLongPtr(handle, GWLP_USERDATA, (LONG) (LONG_PTR) NULL);

    if(handle == NULL) {
      return false;
    }

    ShowWindow(handle, TRUE);
    context->handle = handle;
    return true;
}

void API_CALL_CONVENTION mainLoop(WindowContext* context) {
    MSG msg = { 0 };
    int done = 0;
    // DWORD lastTime = GetTickCount();

    while (!done) {
        int gotMsg = (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) != 0);
        // DWORD curTime = GetTickCount();
        // float deltaTime = (float)( curTime - lastTime ) / 1000.0f;
        // lastTime = curTime;

        if ( gotMsg ) {
            if (msg.message==WM_QUIT) {
                done=1; 
            } else {
                TranslateMessage(&msg); 
                DispatchMessage(&msg); 
            }
        } else {
            SendMessage( context->handle, WM_PAINT, 0, 0 );
        }

        // Call update function if registered
        // if (esContext->updateFunc != NULL ) {
        //     esContext->updateFunc ( esContext, deltaTime );
        // }
    }
}
#![crate_id = "winapi#0.1"]
#![crate_type = "lib"]
extern crate libc;
use libc::types::common::c95::{c_void};
use libc::types::os::arch::c95::{c_int};
use std::ptr::null;

// win32 related types
type LPCWSTR = *u16;
pub type HMODULE = *c_void;

pub struct WindowContext {
    pub width: c_int,
    pub height: c_int,
    pub handle: *c_void
}

#[cfg(windows)]
#[link(name="winapi")]
#[link(name="gdi32")]
extern "stdcall" {
    fn createWindow(context: *WindowContext, title: LPCWSTR) -> bool;
    fn mainLoop(context: *WindowContext);
}

// #[cfg(target_os = "win32", target_arch = "x86")]
#[cfg(windows)]
#[link(name="kernel32")]
extern "system" {
    fn GetModuleHandleW(lpModuleName: LPCWSTR) -> HMODULE;
}

pub fn get_module_handle(name: Option<~str>) -> HMODULE {
    match name {
        Some(n) => std::os::win32::as_utf16_p(n, |buf| unsafe { GetModuleHandleW(buf) }),
        None => unsafe { GetModuleHandleW(null())}
    }
}

pub fn create_window(context: *WindowContext, title: ~str) -> bool {
    std::os::win32::as_utf16_p(title, |buf| unsafe { createWindow(context, buf) })
}

pub fn main_loop(context: *WindowContext) {
    unsafe { mainLoop(context) }
}
extern crate winapi;
use std::ptr::null;

fn main() {
    let handle = winapi::get_module_handle(None);
    println!("handle: {}", handle);
    let context = winapi::WindowContext {
        width: 320,
        height: 240,
        handle: null()
    };
    let result = winapi::create_window(&context, ~"Sample Window");
    if !result {
        println!("Failed to create window");
        return;
    }

    winapi::main_loop(&context);
}
PS C:\Users\masato\Documents\GitHub\rust_sample> cmake -G "MinGW Makefiles"
-- The C compiler identification is GNU 4.8.1
-- The CXX compiler identification is GNU 4.8.1
-- Check for working C compiler: C:/Program Files (x86)/mingw-builds/x32-4.8.1-win32-dwarf-rev5/mingw32/bin/gcc.exe
-- Check for working C compiler: C:/Program Files (x86)/mingw-builds/x32-4.8.1-win32-dwarf-rev5/mingw32/bin/gcc.exe -- w
orks
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files (x86)/mingw-builds/x32-4.8.1-win32-dwarf-rev5/mingw32/bin/g++.exe
-- Check for working CXX compiler: C:/Program Files (x86)/mingw-builds/x32-4.8.1-win32-dwarf-rev5/mingw32/bin/g++.exe --
 works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Users/masato/Documents/GitHub/rust_sample

PS C:\Users\masato\Documents\GitHub\rust_sample> mingw32-make.exe
Scanning dependencies of target winapi
[ 50%] Building C object CMakeFiles/winapi.dir/winapi/winapi.c.obj
Linking C static library libwinapi.a
[ 50%] Built target winapi
Scanning dependencies of target winapi_sample
[100%] Building C object CMakeFiles/winapi_sample.dir/winapi_sample.c.obj
C:\Users\masato\Documents\GitHub\rust_sample\winapi_sample.c: In function 'main':
C:\Users\masato\Documents\GitHub\rust_sample\winapi_sample.c:6:5: warning: format '%x' expects argument of type 'unsigne
d int', but argument 2 has type 'HMODULE' [-Wformat=]
     printf("Module addres: 0x%x\n", addr);
     ^
Linking C executable winapi_sample.exe
[100%] Built target winapi_sample

PS C:\Users\masato\Documents\GitHub\rust_sample> rustc winapi.rs

PS C:\Users\masato\Documents\GitHub\rust_sample> rustc .\main.rs -L .
PS C:\Users\masato\Documents\GitHub\rust_sample> gdb .\main.exe
GNU gdb (GDB) 7.6
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-w64-mingw32".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from C:\Users\masato\Documents\GitHub\rust_sample\main.exe...done.
(gdb) r
Starting program: C:\Users\masato\Documents\GitHub\rust_sample\main.exe
[New Thread 7060.0x1a0c]
[New Thread 7060.0x422c]
handle: 0x400000

Program received signal SIGSEGV, Segmentation fault.
0x76f3fc62 in ntdll!ZwMapViewOfSection () from C:\Windows\system32\ntdll.dll
(gdb) bt
#0  0x76f3fc62 in ntdll!ZwMapViewOfSection () from C:\Windows\system32\ntdll.dll
#1  0x76f3fc62 in ntdll!ZwMapViewOfSection () from C:\Windows\system32\ntdll.dll
#2  0x762ceba2 in MapViewOfFile () from C:\Windows\syswow64\KernelBase.dll
#3  0x70a25313 in UxTheme!GetThemeBitmap () from C:\Windows\SysWOW64\uxtheme.dll
#4  0x70a251e5 in UxTheme!GetThemeBitmap () from C:\Windows\SysWOW64\uxtheme.dll
#5  0x70a253e5 in UxTheme!GetThemeBitmap () from C:\Windows\SysWOW64\uxtheme.dll
#6  0x70a25a77 in UxTheme!GetThemeBitmap () from C:\Windows\SysWOW64\uxtheme.dll
#7  0x70a25cc4 in UxTheme!GetThemeBitmap () from C:\Windows\SysWOW64\uxtheme.dll
#8  0x70a22094 in UxTheme!CloseThemeData () from C:\Windows\SysWOW64\uxtheme.dll
#9  0x70a24260 in UxTheme!IsThemePartDefined () from C:\Windows\SysWOW64\uxtheme.dll
#10 0x70a2421d in UxTheme!IsThemePartDefined () from C:\Windows\SysWOW64\uxtheme.dll
#11 0x70a246ed in UxTheme!ThemeInitApiHook () from C:\Windows\SysWOW64\uxtheme.dll
#12 0x74daacd4 in UnregisterClassW () from C:\Windows\syswow64\user32.dll
#13 0x74daab0e in UnregisterClassW () from C:\Windows\syswow64\user32.dll
#14 0x76f3010a in ntdll!KiUserCallbackDispatcher () from C:\Windows\system32\ntdll.dll
#15 0x0028fa9c in ?? ()
#16 0x74dbc6f1 in USER32!AdjustWindowRect () from C:\Windows\syswow64\user32.dll
#17 0x004cc196 in createWindow@8 (context=0x28fcc8, title=0x9f3618 L"Sample Window")
    at C:\Users\masato\Documents\GitHub\rust_sample\winapi\winapi.c:85
#18 0x00403bfd in create_window::closure.1804 ()
#19 0x00403b8a in os::win32::as_utf16_p::h611005080090069878::v0.1 ()
#20 0x00403a2e in create_window::h0d38b3844b04f5aaEba::v0.1 ()
#21 0x0040174c in main::h8f0d1dbc5859ab98gaa::v0.0 ()
#22 0x0042cac8 in start::closure.7798 ()
#23 0x004c035c in rt::task::Task::run::closure.40266 ()
#24 0x004c46b5 in rt::unwind::Unwinder::try::try_fn::hf6246262045efccdJS9::v0.11.pre ()
#25 0x004cc006 in rust_try ()
#26 0x004c0234 in rt::task::Task::run::h08ef5174e2ea21abwj8::v0.11.pre ()
#27 0x0042c97d in start::h07163dfeb7ec96475Ld::v0.11.pre ()
#28 0x0042c829 in lang_start::h59c5ddaef2ad2b17pLd::v0.11.pre ()
#29 0x00401810 in main ()
(gdb)
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}